C++ std::调用函数时找不到函数构造函数
我有一个函数声明如下;它的确切工作与此无关C++ std::调用函数时找不到函数构造函数,c++,c++11,C++,C++11,我有一个函数声明如下;它的确切工作与此无关 template<typename T> std::pair<int, int> partition3(T *pT, const int N, const T &Kq, const int w, std::function<int(const T&, const T&, int)> P); 模板 std::pair 分区3(T*pT、常数内部N、常数T&Kq、常数内部w
template<typename T>
std::pair<int, int>
partition3(T *pT, const int N, const T &Kq, const int w,
std::function<int(const T&, const T&, int)> P);
模板
std::pair
分区3(T*pT、常数内部N、常数T&Kq、常数内部w、,
std::函数P);
在呼叫站点,我尝试执行以下操作:
bool partition3_test()
{
struct cmp
{
int operator()(int x, int y, int) const
{ return x-y; }
};
int V1[11] = { 3, 7, 1, 7, 7, 8, 10, 2, 16, 4, 3 },
V2[11] = { 3, 6, 1, 6, 6, 8, 10, 2, 16, 4, 3 };
std::function<int(const int&, const int&, int)> F = cmp();
std::pair<int, int>
p1 = partition3(V1, 11, 7, 0, cmp()),
p2 = partition3(V2, 11, 7, 0, cmp());
return false;
}
bool分区3_测试()
{
结构cmp
{
int运算符()(int x,int y,int)常量
{返回x-y;}
};
intv1[11]={3,7,1,7,7,8,10,2,16,4,3},
V2[11]={3,6,1,6,6,8,10,2,16,4,3};
函数F=cmp();
std::pair
p1=分区3(V1、11、7、0、cmp()),
p2=分区3(V2,11,7,0,cmp());
返回false;
}
对于partition3
的两个调用,编译器(MSVC 2010)抱怨它无法推断最后一个参数的模板参数。如果我将cmp()
替换为F
,则代码可以编译并正常工作
我有两个问题:
F
,如何实现相同的效果partition3
上引入另一个模板参数并将p
声明为该模板类型,解决了这个问题。)cmp()
实际上根本不是std::function
。复制初始化工作的事实可能会混淆问题,但它使用的转换构造函数必须使用某种包装器对象,我很惊讶它对临时函子对象工作(啊,检查标准,它显然是函子的副本)
除此之外,函数参数不匹配(passby value和pass by const reference与源代码兼容,但与运行时调用不兼容),这同样需要适配器
最好的解决方案是使模板函数更通用,这样它也可以处理原始函数指针和任意函子对象,而不仅仅是std::function
:
template<typename T, typename Functor>
std::pair<int, int> partition3(T *pT, const int N, const T &Kq, const int w,
const Functor& P);
cmp()
实际上根本不是std::函数。复制初始化工作的事实可能会混淆问题,但它使用的转换构造函数必须使用某种包装器对象,我很惊讶它对临时函子对象工作(啊,检查标准,它显然是函子的副本)
除此之外,函数参数不匹配(passby value和pass by const reference与源代码兼容,但与运行时调用不兼容),这同样需要适配器
最好的解决方案是使模板函数更通用,这样它也可以处理原始函数指针和任意函子对象,而不仅仅是std::function
:
template<typename T, typename Functor>
std::pair<int, int> partition3(T *pT, const int N, const T &Kq, const int w,
const Functor& P);
@Luc:适配器位于std::function
@Luc:它还添加了一个虚拟函数调用。我认为,与我推荐的解决方案相比,接受std::function
会带来开销,这一点很重要。@LucDanton这是有用的信息,他还回答了一个后续问题:使用std::function
是否会带来运行时开销。@BenVoigt您是否会为此支付成本类型擦除,不是由于修改参数(即,即使类型匹配)。您应该澄清一下。@Luc:如果没有类型擦除,一个好的优化器可能会消除内联时调整参数的成本。但这并不完全是虚拟通话增加的成本,因为您可以在没有此类成本的情况下进行虚拟通话。(我考虑的是x64,其中int
参数将在寄存器中传递。接受const int&
参数(它们是必需的地址)的包装器比接受int
参数的包装器做更多的工作,因为两者都引入了阻止内联的虚拟调用。)@Luc:适配器位于std::function
@Luc:它还添加了一个虚拟函数调用。我认为,与我推荐的解决方案相比,接受std::function
会带来开销,这一点很重要。@LucDanton这是有用的信息,他还回答了一个后续问题:使用std::function
是否会带来运行时开销。@BenVoigt您是否会为此支付成本类型擦除,不是由于修改参数(即,即使类型匹配)。您应该澄清一下。@Luc:如果没有类型擦除,一个好的优化器可能会消除内联时调整参数的成本。但这并不完全是虚拟通话增加的成本,因为您可以在没有此类成本的情况下进行虚拟通话。(我考虑的是x64,其中int
参数将在寄存器中传递。接受const int&
参数(它们是必需的地址)的包装器比接受int
参数的包装器做更多的工作,因为两者都引入了阻止内联的虚拟调用。)