【问题标题】:Clean way to put lambda in class definition将 lambda 放入类定义中的干净方法
【发布时间】:2019-11-05 18:07:55
【问题描述】:

我的代码在本地函数中运行良好:

struct Divider
{
public:
    size_t factor;
    size_t next;
};

void foo()
{
    auto cmp = [](const Divider& x, const Divider& y) { return x.next > y.next; };
    std::priority_queue < Divider, std::vector<Divider>, decltype(cmp)> sieve(cmp);
    // ...
}

我现在想将我的sieve 变量移动到一个类中。我可以写出以下怪物:

class Bar
{
    inline static auto cmp = [](const Divider& x, const Divider& y) { return x.next > y.next; };
    std::priority_queue < Divider, std::vector<Divider>, decltype(cmp)> sieve = std::priority_queue < Divider, std::vector<Divider>, decltype(cmp)>(cmp);
};

有没有什么方法可以在不指定类型的情况下编写这个默认构造?或者只是以更清洁的方式。

【问题讨论】:

  • 为什么?为什么这需要是一个 lambda? struct SomeName { auto operator() ... };真的这么啰嗦吗?
  • 我没有得到反对意见,OP 可能走错了方向,可能是 xy 问题,但 x 和 y 都很清楚,问题包含需要回答的所有内容跨度>
  • ..也许我把某些东西解释得太快了;)
  • @nicol,是的,我可以在 Divider 结构中使用 operator(),但对于同一个结构,我还有其他比较函数。
  • @Jeffrey:“我可以在 Divider 结构中使用 operator()”这不是我的意思。我的意思是SomeName 将是一个不同于Divider 的对象,您可以将SomeName 传递给有问题的priority_queue。使用 lambda 只会节省很少的击键次数;有什么意义?

标签: c++ class c++11 lambda class-members


【解决方案1】:

有没有什么方法可以编写这个默认构造 指定类型两次?

是的,你可以!

使用braced-init-list(或uniform-initiation)初始化Bar类的std::priority_queue成员。

class Bar
{
    inline static auto cmp
        = [](const Divider& x, const Divider& y) { return x.next > y.next; };
    std::priority_queue<Divider, std::vector<Divider>, decltype(cmp)> sieve{ cmp };
           //                                                          ^^^^^^^^^^^^^ >> like this
};

或者简单地提供一个compare functor,通过它可以避免将比较器对象传递给std::priority_queue的构造函数。

class Bar
{
    struct Compare final // compare functor
    {
        bool operator()(const Divider& x, const Divider& y) const { 
            return x.next > y.next;
        }
    };
    std::priority_queue<Divider, std::vector<Divider>, Compare> sieve;
    //                                                 ^^^^^^^^^^^^^^^^^ >> like this
};

【讨论】:

    【解决方案2】:

    为了完整起见并提供从字面上理解标题中问题的答案,您可以让成员函数返回 lambda:

    #include <iostream>
    
    struct Bar {
        auto get_compare(){
            return [](){ std::cout << "hello world";};
        }
    };
    
    int main(){
        Bar b;
        b.get_compare()();
    }
    

    当 lambda 不能是静态的时,我会使用它。不过,对于您发布的代码,我肯定更喜欢将 lambda 作为静态成员并通过使用统一初始化(如另一个答案中所述)来消除代码的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多