【问题标题】:Why make_tie is not a thing?为什么 make_tie 不是一个东西?
【发布时间】:2018-11-01 16:39:44
【问题描述】:

有一个流行的成语使用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) &lt; tie(copy-pasta) 对,这背后有什么原因吗?

【问题讨论】:

  • 与“复制成员列表”是指必须复制代码中的参数列表吗?因为tie 没有复制。那我不明白你的问题。如果你愿意,当然你可以写一个MakeTie,虽然你需要为每种类型写一个不同的
  • C++ 中没有必要的反射机制允许您列出所有数据成员。
  • 在你链接的代码中我也没有看到tie( some parameters) &lt; tie (exact same parameters),而是tie (some parameters) &lt; tie (some other parameters),所以我认为这个辅助函数不会真正有帮助,它宁愿混淆代码恕我直言
  • 为什么没有更多的项目使用这个成语?我们只能推测。我认为这个问题只有固执己见的答案。
  • make_tie 不是一个东西,因为没有办法构建它。 C++ 中没有反射,因此您必须自己编写。我见过一个私有的 as_tuple 辅助函数用来代替 tie

标签: c++ c++14 stdtuple


【解决方案1】:

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

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

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

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

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


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

【讨论】:

  • ... 然后某些成员可能不相关。或者可以指向/包含相关成员。或者源顺序可能不是比较顺序。 ...
  • @Deduplicator Right.
  • members_as_tuple_of_references,FTFY。
  • IDK,也许std::tie(a,b,c) &lt; std::tie(a,b,c) 会更好地内联。也许auto TieUp() const; 在某些流行的编译器上根本不会内联。
  • @Abyx :这也是可以想象的
猜你喜欢
  • 1970-01-01
  • 2011-04-27
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
  • 2010-09-06
  • 2012-12-30
相关资源
最近更新 更多