通过“tuple”和“tie”来实现比较运算符,这是一个好主意吗?

(注: tupletie可以从Boost或C ++ 11中取得)
在编写只有两个元素的小型结构时,我有时会倾向于select一个std::pair ,因为所有重要的东西都已经为该数据types完成了,比如operator< for strict-weak-ordering。
缺点虽然是几乎没用的variables名称。 即使我自己创build了typedef ,两天之后我也不会记得firstsecond是什么,特别是如果它们是同一types的话。 这对于两个以上的成员来说更糟,因为嵌套pair非常糟糕。
另一种select是从Boost或C ++ 11中得到一个tuple ,但是看起来并没有更好更清晰。 所以我回到自己编写结构,包括任何需要的比较运算符。
由于特别是operator<可能相当麻烦,所以我想通过仅仅依赖于为tuple定义的操作来规避这个混乱:

operator<例如严格弱sorting的例子:

 bool operator<(MyStruct const& lhs, MyStruct const& rhs){ return std::tie(lhs.one_member, lhs.another, lhs.yet_more) < std::tie(rhs.one_member, rhs.another, rhs.yet_more); } 

tie从所传递的参数构成T&引用。)


编辑 :从@DeadMG私人从tupleinheritance的build议不是一个坏的,但它有一些缺点:

  • 如果运营商是独立的(可能是朋友),我需要公开inheritance
  • 通过投射,我的function/操作员(特别是operator= )可以轻松绕过
  • 有了这个tie解决scheme,如果他们对订购无关紧要,我可以省略某些成员

这个实现有什么缺点,我需要考虑吗?

这肯定会使编写一个正确的操作符比自己滚动它更容易。 如果分析显示比较操作是您的应用程序的一个耗时部分,我会说只考虑一种不同的方法。 否则,维护这一点的难度将超过任何可能的性能问题。

我遇到了同样的问题,我的解决scheme使用c ++ 11 variadic模板。 代码如下:

.h部分:

 /*** * Generic lexicographical less than comparator written with variadic templates * Usage: * pass a list of arguments with the same type pair-wise, for intance * lexiLessthan(3, 4, true, false, "hello", "world"); */ bool lexiLessthan(); template<typename T, typename... Args> bool lexiLessthan(const T &first, const T &second, Args... rest) { if (first != second) { return first < second; } else { return lexiLessthan(rest...); } } 

而没有参数的基本情况下的.cpp:

 bool lexiLessthan() { return false; } 

现在你的例子变成:

 return lexiLessthan( lhs.one_member, rhs.one_member, lhs.another, rhs.another, lhs.yet_more, rhs.yet_more ); 

在我看来,你仍然没有解决std::tuple解决的问题 – 即你必须知道每个成员variables的名字和数量,你需要在函数中重复两次。 你可以selectprivateinheritance。

 struct somestruct : private std::tuple<...> { T& GetSomeVariable() { ... } // etc }; 

这种方法稍微有些乱七八糟,但是你只是把variables和名字保存在一个地方,而不是每个你想要过载的操作符的地方。

如果你打算使用多个运算符重载或者更多的元组方法,我build议把元组作为类的一个成员,或者从元组派生出来。 否则,你在做什么是更多的工作。 在决定两者之间时,一个重要的问题就是:你想让你的class级成为一个元组吗? 如果不是,我会build议包含一个元组,并通过使用委托来限制接口。

您可以创build访问器来“重命名”元组的成员。