0

有一个流行的习惯用法std::tie用来实现比较运算符:

// foo.h
struct Foo {
  int a, b;
  string c;

  bool operator<(const Foo& rhs) const;
};

// foo.cc
bool Foo::operator<(const Foo& rhs) const {
  return tie(a, b, c) < tie(rhs.a, rhs.b, rhs.c);
}

例如,它广泛用于 Chromium

但是它需要复制成员列表,所以为什么不编写一个辅助函数:

static auto MakeTie(const Foo& x) {
  return tie(x.a, x.b, x.c);
}
bool Foo::operator<(const Foo& rhs) const {
  return MakeTie(*this) < MakeTie(rhs);
}

// or, in foo.h
auto MakeTie() const;
// and in foo.cc
auto Foo::MakeTie() const { ... }

(顺便说一句,不能从任何其他翻译单元调用此类成员函数)

那么,为什么我会看到数百对这样的tie(a, b, c) < tie(copy-pasta)对,这背后有什么原因吗?

4

1 回答 1

5

首先,如果你的班级有这么多成员以至于加倍tie是有问题的,那么无论如何你可能有设计的味道。

倾向于同意这有点令人烦恼,但请记住,这不是存在的原因tie。没有“a tie”这样的东西;这里的“tie”是一个动词,一种描述表达式如何“捆绑”成实际上是引用元组的方式。

您当然可以编写自己的替代品,tie以了解您班级中所有相关成员的情况,这样就不需要写两次了。你可以称之为members_as_tuple。是否要这样做取决于您,就像您是否要创建任何函数来避免某些特定的重复代码一样取决于您。

当然,尽管没有反射,C++ 在一般情况下无法为您做到这一点,所以这就是为什么没有开箱即用地提供这种工具的原因。

tl; dr:您已经展示了最好的(唯一?)方法,但我不会称之为make_tie


至于为什么人们没有更多地这样做,嗯,这是无法回答的。他们可能只是没有想到,或者认为他们不需要它,而且可能是对的。

于 2018-11-01T16:48:17.247 回答