Синтаксис шаблонов C ++ с параметрами типа функции - PullRequest
15 голосов
/ 30 августа 2011

Я привык видеть такой синтаксис для указателей на функции

int (*pointer_name) (float, char *);
void call_function (void (*)(int), int);

В некоторых функциональных библиотеках C ++ 03 я вижу типы, используемые следующим образом:

abc::function<void(*)(int,float)> f;

В C ++ 11 std::function я вижу тип, заданный таким образом

std::function<void(int,float)> f;

Отсутствует (*). Почему?

C ++ 03 function<T> имеет T, идентичный типу соответствующего указателя функции. Легко представить себе реализацию.

std::function в C ++ 11 поддерживается улучшениями основного языка. Были ли расширены типы аргументов шаблона для обеспечения возможности вызова?

Ответы [ 4 ]

17 голосов
/ 30 августа 2011

std::function (и его вдохновение boost::function) не только хранят указатели функций. Он также может хранить функциональные объекты. В этом смысле передача сигнатуры функции в качестве параметра шаблона аналогична тому, как интеллектуальный указатель обычно принимает тип pointee в качестве параметра шаблона, а не тип указателя!

Контрастность:

int* p; // indirection to an object of type int
std::unique_ptr<int> q; // indirection to an object of type int

с

typedef void signature_type(); // a function type

// indirection to something callable with signature_type as a signature
// i.e. f() has type void
// only work for freestanding functions however
signature_type* f;

// indirection to something callable with signature_type as a signature
// i.e. g() has type void
// not restricted to function pointers!
std::function<signature_type> g;

Это полезное соглашение.

8 голосов
/ 30 августа 2011

Как и в случае с другими элементами, функции имеют тип, и вы можете использовать либо тип, либо указатель на тип в разных контекстах.Ожидаемый отсутствующий (*) - это просто синтаксис указателя на .

int (*pointer_name) (float, char *);
typedef int my_function_type(float,char*);
my_function_type * pointer_name2;

Типы pointer_name и pointer_name2 одинаковы: указатель нафункция, которая возвращает int и принимает два аргумента типов float и char*.Обратите внимание, что это в точности эквивалентно другим типам, таким как int, с той разницей, что нельзя объявить переменную типа function , только указатель на функцию .

Интерфейс std::function (или boost::function) просто принимает подпись функции.Аргумент типа - это не указатель на функцию , а тип функции (например, my_function_type в приведенном выше коде)

8 голосов
/ 30 августа 2011

Здесь нет ничего волшебного, тип

void(int,float)

- это тип функции без имен.Он соответствует функции, подобной void g(int x, float y).

С шаблонами у вас нет для использования указателей функций, вы также можете использовать типы функций.

3 голосов
/ 30 августа 2011

Типы функций не являются новыми в C ++ 11 (см. 8.3.5 в C ++ 98). IIRC, улучшение по сравнению с тем, что обеспечивают TR1 и boost для function, весьма незначительно.

...