2015-08-31 3 views
3

Я новичок в C++, и я узнал о lambdas, функторах и вызывающих сообщениях, и я знаю, что существует класс-оболочка, а именно std::function, который позволяет хранить и записывать записи различных типов (до тех пор, пока они имеют одну и ту же сигнатуру вызова или тип функции).std :: тип функции и экземпляр шаблона

Теперь я понимаю, что вы можете иметь функции с параметрами типа функции, которые на самом деле просто функционируют параметры указателя как в:

void fun(int,int*(int,int&)); 

, который является не более чем функция, которая принимает Int и функциональный указатель функция как int *f(int,int&), даже если язык позволяет мне передать функцию в качестве аргумента (с или без амперсанд) .Infact, список параметров функции может также быть записана как:

void fun(int,int*(*)(int,int&)); 

Теперь вернемся к std::function Тип

Я знаю, что я могу создать экземпляр std::function с типом функции и который позволяет передавать любые вызовы в оболочку. Но тип функции не тип можно использовать в качестве типа аргумента шаблона в любой конкретизации, такие как:

std::vector<int(int)> f_vec; 

вместо этого, я должен сделать вектор указателей на функции

std::vector<int(*)(int)> f_vec; 

и что будет Позвольте мне вставить указатели в функцию, но не функторы или лямбды.

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

+2

[Как работает std :: function] (http://stackoverflow.com/q/14936539/3953764) –

+0

Тип шаблона 'std :: vector' имеет другое требование, чем для функции std :: '. – Jarod42

ответ

8

Причина, по которой вы не можете написать std::vector<int(int)>, не является чем-то принципиальным в использовании типов функций в качестве параметров шаблона. Это совершенно верно. Это как раз то, что std::vector<T>делает с T (как работает на нем по стоимости), что делает std::vector<int(int)> незаконным.

Это может быть shown с помощью std::vector<int(int)> в контексте, где ничего плохого не происходит, например, как это:

typedef std::vector<int(int)> StillOk; 
StillOk *p = nullptr; 

Пока шаблон фактически не пытаться делать ничего противозаконного с int(int), это нормально.

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

template <class T> 
struct MyPointer 
{ 
    T *p; 
    T& operator*() const { return *p; } 
}; 

Это теперь совершенно законно инстанцирует MyPointer<int(int)> и использовать его operator *, потому что это будет только когда-либо включать выражения типа int (*)(int) и int (&)(int). [Live example]

И это в значительной степени и то, что делает std::function<T> с его T — только вещи, которые являются законными с типом функции.

+0

ОК, поэтому я понимаю, что тема действительно глубже и что мне нужно вникать в нее «немного» больше ... но теперь вы меня смутили, я знаю о указателях функций, но ссылки на функции? – Luca

+0

@Luca Да, существуют ссылки на функции. 'void (& alias)() = foo;' отлично. – Angew

+0

и как их использовать? Я имею в виду, если я определяю параметр функции типа функции, который обрабатывается автоматически как указатель на функцию, так как ссылки на функцию вписываются в изображение? – Luca

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