gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 06:57:11 24 4
gpt4 key购买 nike

在使用算法时,我对以下差异感到困惑。

首先,算法可以毫无问题地使用 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);

现在让我们定义模板化比较器,

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 和 comp2 几乎相同(从推论参数所需的信息量的意义上来说)。但 comp1 不起作用。

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

即,函数模板、模板operator()(模板仿函数?)和通用 lambda 在参数推导方面的主要区别是什么?

谢谢。

最佳答案

模板是 C++ 的一种语言构造,它生成其他构造:类、函数或变量(在 C++14 中)。没有模板参数的模板名称只能以非常有限的方式使用。

comp1命名一个模板,而不是一个函数。这就是重点。函数模板是一种构造,当您提供特定的模板参数时,它会生成一个函数; comp1<int>是函数的名称。但名称本身命名了模板,而不是它生成的函数。

函数模板的名称可以被调用(即: comp1(arg1, arg2) ),因为 C++ 有一个特殊的规则,称为“模板参数推导”。简而言之,编译器将模板参数的类型推导为 comp基于comp的声明以及提供给函数调用的参数的性质。但这只是因为 C++ 有一条规则表明它确实有效。

单独的模板名称(如 comp1 )不是表达式,函数调用需要将表达式(或大括号初始化列表)作为参数给出。错误“无法推导参数错误”与 std::sort 内的推导无关。 ;这是关于推导 std::sort 的模板参数本身。 comp1 ,一个模板,没有类型,因此不能参与参数推导。

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

是的,comp2 的类型和comp3 包含一个函数模板。但是comp2comp3 作为名称命名变量,而不是它们包含的函数模板。因此它们的工作方式与任何其他变量一样。

对于通用 lambda,它与任何其他带有模板的用户定义类型没有什么不同 operator()方法。

关于c++ - 在参数推导过程中,泛型 lambda、模板函数和模板成员 operator() 之间的主要区别是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64019911/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com