Я определил шаблон класса с именем CallBackAtInit
единственная цель которого — вызвать функцию при ее инициализации (конструктор). Функция указана в параметрах шаблона. Проблема в том, что шаблоны не принимает std::function
в качестве параметров; но они принимают указатели функций. Зачем?
Вот мой код:
#include <iostream>
#include <functional>
/* Does not work:*/ template <typename return_type, typename arg_type, std::function<return_type(arg_type)> call_back>
/* Work fine: */// template <typename return_type, typename arg_type, return_type(*call_back)(arg_type)>
class CallBackAtInit {
public:
CallBackAtInit(arg_type arg)
{
call_back(arg);
};
};
void printInt(int i);
class HoldInt : private CallBackAtInit<void, int, printInt> {
public:
HoldInt(int integer)
: CallBackAtInit(integer)
{}
// ...
};
int main(int argc, char** argv)
{
HoldInt hi(10);
return 0;
}
void printInt(int i)
{
std::cout << i << std::endl;
}
параметр Для определения шаблона может быть четыре вида:
std::nullptr_t
(начиная с C ++ 11)Когда вы упоминаете std::function
в определении шаблона он не попадает ни в одну из вышеуказанных категорий. Шаблон не может принять типы, и не может принять интегральное значение, или же значение указателя на член.
Когда параметр тип указателя функции, тогда он может принимать указатель на функцию (адрес функции, соответствующей типу), которая является просто интегральным значением. Обратите внимание, что адрес всегда является интегральным значением. Так что он попадает во вторую категорию, поэтому он работает.
Потому что это не разрешено стандартом:
14.1 Параметры шаблона
4 Нетипичный шаблон-параметр должен иметь одно из следующих
(необязательно cv-квалифицированные) типы:— целочисленный или перечислимый тип,
— указатель на объект или указатель на функцию,
— lvalue ссылка на объект или lvalue ссылка на функцию,
— указатель на член,
— std :: nullptr_t.