我是C ++的新手,我正在学习lambdas,functor和callables,我知道有一个包装类,即std::function
,它允许存储和调用不同类型的callable(只要很长时间)因为它们具有相同的呼叫签名或功能类型)。
现在,我知道你可以使用函数类型参数来实现函数指针参数,如下所示:
void fun(int,int*(int,int&));
它只不过是一个函数,它接受一个int和一个函数指针到int *f(int,int&)
之类的函数,即使该语言允许我将函数作为参数传递(带或不带符号)。 ,函数参数列表也可以写成:
void fun(int,int*(*)(int,int&));
现在,返回std::function
类型
我知道我可以使用函数类型实例化std::function
,并允许将任何类型的可调用传递给包装器。但是,函数类型不是我可以在任何实例化中用作模板类型参数的类型,例如:
std::vector<int(int)> f_vec;
相反,我应该创建一个函数指针的向量
std::vector<int(*)(int)> f_vec;
这将允许我插入指向函数的指针,但不能插入函子或lambda。
所以,我的问题是,如何使用类型参数实例化模板,如函数类型?在库std::function
类型的引擎盖下发生了什么。我的意思是函数类型在我看来是一种我不能在模板中使用的类型?请求你能让事情变得更加清晰,因为我刚开始学习这些话题。感谢
答案 0 :(得分: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
所做的事情 - 只有与函数类型合法的事情。