lambda 可以替代 getter 吗?

发布于 2024-12-20 16:01:01 字数 1049 浏览 0 评论 0原文

下面是一个类的字段有两个 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 和 y 做一些完全不同的事情。那么他显然需要以某种方式到达 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,这对我来说似乎是可行的。这种方法实际上比带有吸气剂的第一个版本更合理,还是我有点太热情了?

你怎么认为?它的适用范围有多广?我有什么遗漏的吗?是否可以改进?

Here is a classic example of a class with two getters for its fields:

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';
}

One could argue that printing a point to an output stream should really be provided by an overload of operator<<, but let's suppose that a client wants to print in his own favorite format or do something completely different with x and y. Then he clearly needs to get to the x and y fields somehow, right?

A basic principle of object-oriented programming is "tell, don't ask". That is, ideally I should tell my object to do something with the x and y fields instead of asking for them. That led me to the following idea:

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';
    });
}

This would have been too clumsy in C++98, but now that we have lambdas, it seems feasible to me. Is this approach actually more sound than the first version with the getters, or am I a bit too enthusiastic?

What do you think? How widely applicable is it? Is there something I'm missing? Could it be improved?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一指流沙 2024-12-27 16:01:01

这在 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);
}

可以改进吗?

是:删除吸气剂并将 x 和 y 放入公共部分:

struct point
{
  int x;
  int y
};

This would have been too clumsy in C++98

Actually, it is quite easy (at least in 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);
}

Could it be improved?

Yes : remove getters and put x and y in the public section :

struct point
{
  int x;
  int y
};
寄居者 2024-12-27 16:01:01
p([](int x, int y){
    std::cout << x << ", " << y << '\n';
});

在我看来,必须围绕某些代码编写 lambda 而不仅仅是编写代码仍然是样板代码。

拥有单独的访问器与此之间的唯一区别是该类可以假设这些值总是一起访问。这可能会提供生成这些值的新方法,如果这些值必须单独生成,则不可能实现这些值(例如,一次请求 2 个值可能比对一个值发出 2 个请求要便宜得多) 。

对于许多类(例如 Point)来说,后者几乎不是这种情况,在这些类中,以更复杂的使用为代价并没有真正的收益。

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

IMO, having to write the lambda around some code instead of just writing the code is still boiler-plate.

The only difference between having individual accessors and this is that the class can assume that the values are always accessed together. This just might provide new ways of producing those values that wouldn't be possible if they each had to be produced individually (e.g perhaps it is a lot cheaper to request 2 values at a time, rather than to make 2 requests for one value).

The latter is hardly the case for many classes (such as Point), where there's no real gain for the expense of more complicate usage.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文