c++ - Lamda 仅在声明为 'auto' 时编译,而不是在声明为 'bool' 时编译

标签 c++ c++11 templates c++14

考虑下面的模板函数 sort(...)。这是一个围绕 std::sort 的包装函数。目的是在对用户定义类的 vector 进行排序时提供更好的语法。第一个参数是要排序的 vector 。第二个参数是一个函数,指定如何对 vector 进行排序(在哪个公共(public)成员变量或函数上)。

std::sort 需要一个比较函数来对 vector 中的不同项目进行排序。这在我的排序函数中被声明为 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;
}

最佳答案

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,您将不可避免地遇到编译器错误。

关于c++ - Lamda 仅在声明为 'auto' 时编译,而不是在声明为 'bool' 时编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51235135/

相关文章:

c++ - c++20 模板 lambda 的用例是什么?

c++ - 如何从结果创建并发::任务?

c++ - 双参数构造函数的用户定义文字

Visual Studio中的C++运行结构

c++ - 使用 enable_if 和 is_integral 来制作分布特征

c++11 - 使用 std::mutex 作为类中的成员变量

c++ - #includes 在命名空间中,到 "embed"命名空间中的预写内容

c++ - 使用列表初始化(花括号)分配 vector 大小

c++ - 模板继承(在子类成员函数中访问父类的变量和对象)

c++ - 在 Qt 中使用带有 QSet 和 boost::tuples::tuple 的模板没有匹配错误