lambda可以取代吸气剂吗?

时间:2011-12-10 09:14:06

标签: c++ oop lambda c++11 getter

以下是一个类的经典示例,其中包含两个用于其字段的getter:

class point
{
    int x_, y_;

public:

    point(int x, int y) : x_(x), y_(y) {}

    int x() const
    {
        return x_;
    }

    int y() const
    {
        return y_;
    }
};

int main()
{
    point p(1, 2);
    std::cout << p.x() << ", " << p.y() << '\n';
}

有人可能认为打印输出流的点应该由operator<<的重载提供,但是假设客户想要以他自己喜欢的格式打印或者做一些与x完全不同的事情。年。然后他显然需要以某种方式到达x和y字段,对吧?

面向对象编程的基本原则是“告诉,不要问”。也就是说,理想情况下,我应该告诉我的对象用x和y字段做某事而不是要求它们。这让我想到了以下想法:

class point
{
    int x_, y_;

public:

    point(int x, int y) : x_(x), y_(y) {}

    template<typename Fun>
    void operator()(Fun fun) const
    {
        fun(x_, y_);
    }
};

int main()
{
    point p(3, 4);
    p([](int x, int y){
        std::cout << x << ", " << y << '\n';
    });
}

这在C ++ 98中太笨拙了,但是现在我们有了lambda,这对我来说似乎是可行的。这个方法实际上比第一个带有吸气剂的版本更合理,还是我有点过于热情?

你怎么看?它有多广泛适用?有什么我想念的吗?可以改进吗?

2 个答案:

答案 0 :(得分:4)

  

这在C ++ 98中太笨拙了

实际上,它很容易(至少在c ++ 03中):

class point
{
    int x_, y_;

public:

    point(int x, int y) : x_(x), y_(y) {}

    template<typename Fun>
    void operator()(Fun fun) const
    {
        fun(x_, y_);
    }
};

void foo(int,int)
{
}

int main()
{
    point p(3, 4);
    p(&foo);
}
  

可以改进吗?

是:删除getter并将x和y放在公共部分:

struct point
{
  int x;
  int y
};

答案 1 :(得分:3)

p([](int x, int y){
    std::cout << x << ", " << y << '\n';
});

IMO,不得不围绕某些代码编写lambda,而不仅仅是编写代码仍然是样板。

拥有单个访问器与此之间的唯一区别是,类可以假定值始终一起访问。这可能提供了生成这些值的新方法,如果每个值都必须单独生成,那么这些值是不可能的(例如,一次请求2个值可能要便宜得多,而不是对一个值进行2次请求)

后者对于许多类(例如Point)来说并非如此,因为更复杂的使用费用并没有真正的好处。