Подтвердить что ты не робот

Синтаксис шаблонов С++ с параметрами типа функции

Я использую синтаксис, подобный этому для указателей на функции

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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;

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

Ответ 2

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

void(int,float)

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

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

Ответ 3

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

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, с той разницей, что вы не можете объявить переменную функцией типа, только указателем на функцию.

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

Ответ 4

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