2014-11-07 2 views
2

std::function класс шаблонный таким образом, что, когда мы хотим, чтобы обернуть функцию, как следующее:Функциональные подписи в C++ шаблоны

void printInt(int integer) 
{ 
    std::cout << int << '\n'; 
} 

Мы используем std::function<void(int)>. До недавнего времени я думал, что это был странный нюанс класса, но a class I found при поиске делегирования в C++ использует аналогичный синтаксис.

Что именно являетсяvoid(int), и что мы называем это техническими терминами? Кажется, это стандартный способ сказать «функция, которая принимает int и возвращает void» в кодексе, но мой инстинкт кишки говорит, что это ужасно упрощено.

Во-вторых, я заметил, что когда я вижу шаблоны, использующие этот синтаксис, они используют вариативные шаблоны, чтобы можно было сопоставить несколько сигнатур функций. Из приведенной выше ссылке:

template <typename T> class delegate; 

template<class R, class ...A> 
class delegate<R (A...)> 
{ 
... 

Что является причиной для объявления функции как таковой, вместо того, чтобы просто используя следующие:

template<class R, class ...A> 
class delegate 
{ 
... 

ответ

3

Параметр шаблона std::function<Signature> просто просто тип функции, т.е. его подпись. Он использует ту же самую нотацию, что и любое объявление функции, за исключением того, что он не указан и имя не указано. Возможно, вы столкнулись с указателями функций, которые используют одну и ту же нотацию, но сигнатура функции используется для указателя.

Причина std::function<Signature> (и, видимо, delegate<Signature>) реализованы с использованием шаблона специализации, чтобы получить более хороший тип:

template <typename T> class function; 
template <typename R, typename... Args> 
class function { 
public: 
    R operator()(Args...); 
    // ... 
}; 

template <typename R, typename... Args> 
class other { 
public: 
    R operator()(Args...); 
    // ... 
}; 

int main() { 
    function<int(double, char)> f; 
    other<int, double, char> o; 
} 

Так как основной шаблон для function<T> занимает один типа в качестве аргумента, используя специализацию аргумент может быть нормальным типом функции. С другой стороны, то же самое не делается для other<T...>, который, таким образом, получает список типов.

Не стоит ничего, что std::function<T> объекты могут быть легко переданы без каких-либо проблем со многими аргументами шаблона: поскольку подпись функции является всего лишь типом, этот шаблон шаблона принимает только один аргумент шаблона.

+0

Итак, эта часть * на самом деле * называется сигнатурой функции? Думаю, я знал этот термин в конце концов ... Хорошее объяснение, спасибо! – Conduit

Смежные вопросы