Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++ 在参数推导过程中,泛型lambda、模板函数和模板成员运算符()之间的主要区别是什么?_C++_Templates_C++14 - Fatal编程技术网

C++ 在参数推导过程中,泛型lambda、模板函数和模板成员运算符()之间的主要区别是什么?

C++ 在参数推导过程中,泛型lambda、模板函数和模板成员运算符()之间的主要区别是什么?,c++,templates,c++14,C++,Templates,C++14,当与算法一起使用时,我对以下差异感到困惑 首先,算法使用lambda、函数和函子,没有任何问题。比如说, bool comp (int t1, int t2) { return t1 > t2; } std::array<int, 10> myArray{5, -10, 3, 2, 7, 8, 9, -4, 3, 4}; std::sort(myArray.begin(), myArray.end(), comp); bool comp(int t1,int t2){

当与算法一起使用时,我对以下差异感到困惑

首先,算法使用lambda、函数和函子,没有任何问题。比如说,

bool comp (int t1, int t2) {
    return t1 > t2;
}
std::array<int, 10> myArray{5, -10, 3, 2, 7, 8, 9, -4, 3, 4};
std::sort(myArray.begin(), myArray.end(), comp);
bool comp(int t1,int t2){
返回t1>t2;
}
数组myArray{5,-10,3,2,7,8,9,-4,3,4};
排序(myArray.begin(),myArray.end(),comp);
现在让我们定义模板比较器

template<typename T>
bool comp1(T t1, T t2) {
    return t1 > t2;
}

struct Comp {
    template<typename T>
    bool operator()(T t1, T t2) const {
        return t1 > t2;
    }
};
Comp comp2;

auto comp3 = [](auto t1, auto t2) { return t1 > t2; }


template<typename Container>
void sortDescending(Container &c) {
    std::sort(c.begin(), c.end(), comp1); // cannot deduce argument error
    std::sort(c.begin(), c.end(), comp2); // works
    std::sort(c.begin(), c.end(), comp3); // works
}

sortDescending(myArray);
模板
布尔comp1(t1,t2){
返回t1>t2;
}
结构组件{
模板
布尔运算符()(t1,t2)常数{
返回t1>t2;
}
};
Comp comp2;
自动comp3=[](自动t1,自动t2){返回t1>t2;}
模板
无效分拣分拣(集装箱和集装箱){
std::sort(c.begin(),c.end(),comp1);//无法推断参数错误
排序(c.begin(),c.end(),comp2);//有效
排序(c.begin(),c.end(),comp3);//有效
}
排序下降(myArray);
函数模板在上述场景中不起作用,这让我感到困惑

对我来说,至少comp1和comp2几乎是一样的(从这个意义上说,推导参数所需的信息量)。但是comp1不起作用

所以我的问题是,这种差异背后的最终原因是什么

例如,函数模板、模板运算符()(模板函子?)和通用lambda在参数推导方面的主要区别是什么


谢谢。

comp1
是一个模板;虽然
Comp
和lambda闭包类型不是,但它们只有模板运算符。使用参数调用functor时,模板参数推断在
std::sort
内部执行,而不是在传递给
std::sort
时执行。在第一种情况下,没有此类函数参数可用于推断
comp1
,您必须明确指定模板参数,例如

std::sort(c.begin(), c.end(), comp1<typename Container::value_type>);
排序(c.begin(),c.end(),comp1);
<>代码>模板是C++的语言结构,它生成其他结构:类、函数或变量(C++ 14)。没有模板参数的模板名称只能以非常有限的方式使用

comp1
命名模板,而不是函数。这是重要的一点。函数模板是在提供特定模板参数时生成函数的构造
comp1
是函数的名称。但是名称本身命名模板,而不是它生成的函数

函数模板的名称可以被调用(即:代码> COMP1(ARG1,ARG2)< /COD>),因为C++的一个特殊规则称为“模板参数推导”。简而言之,编译器根据

comp
的声明和提供给函数调用的参数的性质,推断出
comp
模板参数的类型。但这只是因为C++有一个规则,它确实是这样。

模板本身的名称(如
comp1
)不是表达式,函数调用要求表达式(或带括号的init列表)作为参数提供。错误“无法推断参数错误”与
std::sort
中的推断无关;它是关于推导
std::sort
本身的模板参数<模板code>comp1没有类型,因此无法参与参数推导

comp2
命名变量,就像
comp3
命名变量一样。这两个都是表达式,因此都可以传递给函数

是的,
comp2
comp3
的类型都包含函数模板。但是
comp2
comp3
作为名称变量,而不是它们包含的函数模板。所以它们和其他变量一样工作


对于一个通用的lambda,与模板<代码>操作程序()/<代码>方法的任何其他用户定义类型没有什么不同。至少对于我来说,我认为模板>代码>作为C++代码生成器元语言,它比使用宏替换和宏替换功能的C预处理器强大得多。虽然语法有点笨拙。(我提到这一点是希望它有助于你的困惑。)