为什么make_tie不是东西?

时间:2018-11-01 16:39:44

标签: c++ c++14 stdtuple

使用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);
}

E.g. it's widely used in 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)对,这背后有什么原因吗?

1 个答案:

答案 0 :(得分:5)

首先,如果您的班级成员太多,以至于将tie加倍是有问题的,那么您仍然可能会有设计上的味道。

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

您当然可以编写自己的tie替代品,该替代品知道您班上所有相关成员的情况,因此无需写两次。您可以将其称为members_as_tuple。是否要执行此操作由您决定,就像是否执行任何函数来避免某些特定的重复代码由您决定。

尽管如此,毫无疑问,在一般情况下C ++不能为您做到这一点,所以这就是为什么没有开箱即用地提供这种功能的原因。

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


关于人们为什么不做更多的事情,这是无法回答的。他们可能只是没有想到它,或者不认为自己需要它,而且可能是正确的。