Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::调用函数时找不到函数构造函数_C++_C++11 - Fatal编程技术网

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
,则代码可以编译并正常工作

我有两个问题:

  • 为什么我会出错?[编译器错误或一些神秘的C++规则?] < /LI>
  • 如果不先显式构造
    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
    参数的包装器做更多的工作,因为两者都引入了阻止内联的虚拟调用。)