【问题标题】:lambda failed on C++14/17 and works on later versionlambda 在 C++14/17 上失败,适用于更高版本
【发布时间】:2020-05-14 20:05:47
【问题描述】:

我有一个优先级队列定义在 C++14/17 上失败,但适用于后来的标准。 谁能告诉我为什么?

    auto compare = [](const pair<int, int>& p1, const pair<int, int>& p2) {
        return p1.second < p2.second;
    };

    // compile failure on C++ 14/17 
    priority_queue<pair<int, int>, vector<pair<int, int>>, decltype(compare)> pq;

我可以问一个未来的问题吗?为什么使用 lambda 的第一种情况很好,但第二种情况是错误的:

auto comp = [&](const pair<string,int>& a, const pair<string,int>& b) {
    return a.second > b.second || (a.second == b.second && a.first < b.first);
};
// OK!!!
// typedef priority_queue< pair<string,int>, vector<pair<string,int>>, decltype(comp)> my_priority_queue_t;
// my_priority_queue_t  pq(comp);

// BOMB!!!
priority_queue< pair<string,int>, vector<pair<string,int>>, decltype(comp)> pq;

【问题讨论】:

  • 在 c++20 之前,lambda 不能默认构造。
  • 只是补充@rafix07 注释,std::priority_queue 的第三个模板参数接收一个类型,而不是一个值。然后在内部 std::priority_queue 将从该类型创建一个 lambda。这只有在 C++20 版本之后才有可能,其中允许默认构造的 lambda。事实上,我认为这个特殊用例是使 lambdas 默认可构造的主要动机。

标签: lambda c++17 c++20


【解决方案1】:

你调用priority_queue的如下构造函数:

priority_queue() : priority_queue(Compare(), Container()) { }

来自reference。如您所见,它调用Compare() - 比较器的默认构造函数,在您的情况下是闭包类型。但是在 C++20 之前,闭包不是默认可构造的。这就是为什么构造函数的重载不起作用的原因。

从 C++20 开始,这一切都很好,因为闭包有:

ClosureType() = default;
(since C++20)(only if no captures are specified)

来自lambdas reference

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 2018-08-24
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 2019-04-21
    相关资源
    最近更新 更多