std :: function type和template instantiation

Luc*_*uca 3 c++ lambda templates c++11 std-function

我是C++的新手,我正在学习lambdas,functor和callables,我知道有一个包装类,即std::function允许存储和调用不同类型的callables(只要具有相同的调用签名,或功能类型).

现在,我明白你可以使用函数类型参数来实现函数指针参数,如下所示:

void fun(int,int*(int,int&));
Run Code Online (Sandbox Code Playgroud)

它只不过是一个函数,它接受一个int函数指针和一个函数指针int *f(int,int&),即使该语言允许我将函数作为参数传递(带或不带符号).事实上,函数参数列表也可能写成:

void fun(int,int*(*)(int,int&));
Run Code Online (Sandbox Code Playgroud)

现在,回到std::function类型

我知道我可以std::function使用函数类型进行实例化,并允许将任何类型的可调用函数传递给包装器.但是,函数类型不是我可以在任何实例化中用作模板类型参数的类型,例如:

std::vector<int(int)> f_vec;
Run Code Online (Sandbox Code Playgroud)

相反,我应该制作一个函数指针的向量

std::vector<int(*)(int)> f_vec;
Run Code Online (Sandbox Code Playgroud)

这将允许我插入指向函数的指针,但不能插入函子或lambda.

所以,我的问题是,如何使用类型参数实例化模板,如函数类型?在库std::function类型的引擎盖下发生了什么.我的意思是一个函数类型在我看来是一个我不能在模板中使用的类型?请求你能让事情变得更加清晰,因为我刚开始学习这些话题.谢谢

Rei*_*ica 8

你不能写的原因并不是将std::vector<int(int)>函数类型用作模板参数的基础.这完全有效.这只是什么std::vector<T> T(按价值计算一样操作就可以了),这使得std::vector<int(int)>非法的.

这可以通过在没有发生任何不良事件的上下文中使用来显示std::vector<int(int)>,例如:

typedef std::vector<int(int)> StillOk;
StillOk *p = nullptr;
Run Code Online (Sandbox Code Playgroud)

只要模板实际上没有尝试做任何违法的事情int(int),就可以了.

因此,只要您的模板以对函数类型合法的方式处理其模板参数,您就可以将它与函数类型一起使用.这是一个假设的例子:

template <class T>
struct MyPointer
{
  T *p;
  T& operator* () const { return *p; }
};
Run Code Online (Sandbox Code Playgroud)

它现在完全合法地实例化MyPointer<int(int)>和使用它operator *,因为它只涉及类型int (*)(int)和表达式int (&)(int).[实例]

而且这也std::function<T>与其T功能类型合法的东西有什么关系.