请考虑以下模板函数sort(...)。这是围绕std :: sort的包装函数。目的是在对用户定义的类的向量进行排序时提供更好的语法。第一个参数是要排序的向量。第二个参数是一个函数,指定如何对向量进行排序(在哪个公共成员变量或函数上)。
std :: sort需要比较功能才能对向量中的不同项目进行排名。这在我的sort-function中声明为lambda。但是,仅当lambda声明为“ auto”时才编译此代码,而如果声明为bool则不会编译。我觉得这很奇怪。有人可以解释一下吗?
(代码应该按现在的样子进行编译。要观察该问题,请取消注释以“ bool”开头的行)。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
// Copy function is needed in sort(...), below
template<typename T>
auto copy(const std::vector<T>& v)
{
auto r = std::vector<T>();
r.reserve(v.size());
for(const auto & e : v) {
r.push_back(e);
}
return std::move(r);
}
template<typename T, typename F>
auto sort(const std::vector<T>& v, const F& f)
{
auto r = copy(v);
// ///////////// Consider the following line: /////////////////
// bool compare = [=](const T& lhs, const T& rhs) // does not compile, why?
// auto compare = [=](const T& lhs, const T& rhs) -> bool // compiles
auto compare = [=](const T& lhs, const T& rhs) // compiles
{
return f(lhs) < f(rhs);
};
std::sort(r.begin(), r.end(), compare);
return std::move(r);
}
struct Foo {
int id;
string message;
};
int main()
{
auto unordered = vector<Foo>();
unordered.push_back(Foo{2, "the last element"});
unordered.push_back(Foo{1, "the first element"});
// I want to sort the vector by 'id'.
auto ordered = sort(unordered, [](const auto& e) { return e.id; });
cout << "Ordered vector (by id):" << endl;
for(const auto& e : ordered) {
cout << e.id << ", " << e.message << endl;
}
return 0;
}
答案 0 :(得分:3)
lambda的类型由实现定义。因此,如果您要声明一个变量来保存lambda,则该变量必须始终为auto
类型。您似乎将lambda的返回类型与实际包含lambda本身的变量类型混淆了。
// variable type | variable identifier | lambda expression (return type deduced)
bool compare = [=](const T& lhs, const T& rhs)
// variable type | variable identifier | lambda expression | return type
auto compare = [=](const T& lhs, const T& rhs) -> bool
// variable type | variable identifier | lambda expression (return type deduced)
auto compare = [=](const T& lhs, const T& rhs)
上表说明了声明的每个部分所涉及的内容。在您的代码中,compare
是一个lamda。如果您声明类型为bool
的变量,然后尝试为其分配一个lamda,则不可避免地会出现编译器错误。