函数类型和模板实例化

std::function type and template instantiation

本文关键字:实例化 类型 函数      更新时间:2023-10-16

我是c++的新手,我正在学习lambda,函子和可调用对象,并且我知道有一个包装类,即std::function,允许存储和调用不同类型的可调用对象(只要它们具有相同的调用签名或函数类型)。

现在,我明白你可以有函数类型参数的函数,实际上只是函数指针参数,如:

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类型中发生了什么。我的意思是函数类型对我来说是一种我不能在模板中使用的类型??请您讲得更清楚一些,因为我才刚刚开始学习这些主题。由于

不能写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;

只要模板实际上没有试图对int(int)做任何非法的事情,就可以。

所以,只要你的模板以一种对函数类型合法的方式处理它的模板形参,你就可以在函数类型中使用它。下面是一个假设的例子:

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

现在实例化MyPointer<int(int)>并使用它的operator *是完全合法的,因为它只涉及int (*)(int)int (&)(int)类型的表达式。(生活例子)

这也是std::function<T>T中所做的,只有函数类型是合法的