|
Шаблоны функций
Перегруженные функции обычно используются для выполнения похожих операций над различными типами данных. Простой пример такой функции в MQL5 - ArraySize(), которая возвращает размер массива любого типа. На самом деле эта системная функция является перегруженной, и вся реализация такой перегрузки спрятана от разработчика программ на MQL5:
int ArraySize( |
То есть на самом деле компилятор языка MQL5 подставляет для каждого вызова этой функции нужную реализацию, например, для массивов целого типа примерно так:
int ArraySize( |
А для массива типа MqlRates для работы с котировками в формате исторических данных функцию ArraySize() можно представить таким образом:
int ArraySize( |
Таким образом, очень удобно использовать одну и ту же функцию для работы с разными типами, но необходимо самостоятельно провести всю предварительную работу, а именно – сделать перегрузку нужной функции для всех типов данных, с которыми она должна будет корректно работать.
Есть более удобное решение – если для каждого типа данных должны выполняться идентичные операции, то более компактным и удобным решением является использование шаблонов функций. При этом программисту нужно написать всего одно описание шаблона функции. При таком описании шаблона в качестве параметра достаточно указать не конкретный тип данных, с которыми должна работать функция, а некий формальный параметр. Основываясь на типах аргументов, использованных при вызове этой функции, компилятор будет автоматически генерировать разные функции для соответствующей обработки каждого типа.
Определение шаблона функции начинается с ключевого слова template, после которого в угловых скобках идет список формальных параметров. Каждый формальный параметр предваряется ключевым словом typename. Формальные типы параметров – встроенные типы или типы, определенные пользователем. Они используются:
·для задания типов аргументов функции,
·для задания типов возвращаемого значения функции,
·для объявления переменных внутри тела описания функции
Количество параметров в шаблоне не может быть больше восьми. Каждый формальный параметр в определении шаблона должен хотя бы один раз появиться в списке параметров функции. Каждое имя формального параметра должно быть уникальным.
Вот пример шаблона функции для поиска максимального значения в массиве любого числового типа (целые и вещественные числа):
template<typename T> |
Данный шаблон описывает функцию, которая находит максимальное значение в переданном массиве и возвращает его в качестве результата. Напомним, что встроенная в MQL5 функция ArrayMaximum() возвращает только индекс найденного максимального значения, по которому пользователь в дальнейшем может получить уже и само значение. Например, так:
//--- создадим массив |
Таким образом, нам понадобилось два действия, чтобы получить максимальное значение в массиве. С помощью шаблона функции ArrayMax() можно получить результат нужного типа, просто передав в неё массив соответствующего типа. То есть вместо двух последних строчек
//--- найдем позицию максимального элемента в массиве |
теперь мы можем использовать одну строку, возвращающую сразу результат того же типа, что и переданный массив:
//--- найдем максимальное значение |
При этом тип результата, возвращенный функцией ArrayMax(), будет автоматически соответствовать типу массива.
Для создания универсальных способов работы с различными типами данных необходимо использовать ключевое слово typename для получения типа аргумента в виде строки. Покажем это на примере функции, которая возвращает в виде строки тип данных:
#include <Trade\Trade.mqh> |
Шаблоны функций можно также использовать и для методов класса, например:
class CFile |
Шаблоны функций нельзя объявлять с ключевыми словами export, virtual и #import.