C++ 在参数推导过程中,泛型lambda、模板函数和模板成员运算符()之间的主要区别是什么?
当与算法一起使用时,我对以下差异感到困惑 首先,算法使用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){
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,与模板<代码>操作程序()/<代码>方法的任何其他用户定义类型没有什么不同。至少对于我来说,我认为