有一个流行的习惯用法,它使用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)
对,这背后有什么原因吗? 最佳答案
首先,如果您的班级成员太多,以至于将tie
加倍是有问题的,那么您可能总有一种设计味道。
我倾向于同意这有点烦人,但请记住,这不是tie
存在的原因。没有“ a tie
”这样的东西; “ tie”是动词,是一种将表达式如何“绑在一起”成实际上是引用元组的方式。
当然,您可以编写自己的tie
替代品,该替代品知道类中所有相关成员的方式,因此无需写两次。您可以将其称为members_as_tuple
。是否要执行此操作由您决定,就像是否要执行任何功能来避免某些特定的重复代码一样,这取决于您。
当然,尽管如此,在没有反思的情况下,C ++通常无法为您做到这一点,因此这就是为什么没有开箱即用地提供这种功能的原因。
tl; dr:您已经展示了最佳的(唯一的)方法,但是我不会将其称为make_tie
。
至于为什么人们没有做更多的事情,那是无法回答的。他们可能只是没有想到它,或者没有想到他们需要它,而且可能是正确的。