C++11 introduces the interesting std::tuple feature.
Here, I will present the usage of std::tie to implement comparison operators in a class.
Let’s say we have to implement operator== in a class that consists in comparing every member of that class. Here is a typical implementation:
1 2 3 4 5 6 7 8 9 10 |
struct X { int a; double b; string c; bool operator==(const X &rhs) const { return a == rhs.a && b == rhs.b && c == rhs.c; } }; |
It is possible to implement the operator== using the new standard function std::tie as follows:
1 2 3 4 5 6 7 8 |
struct X { ... bool operator==(const X &rhs) const { return tie(a, b, c) == tie(rhs.a, rhs.b, rhs.c); } }; |
With the future C++14 standard, it will be possible to avoid code repetition:
1 2 3 4 5 6 7 |
struct X { ... bool operator==(const X &rhs) const { return tied() == rhs.tied(); } private: auto tied() const { return tie(a, b, c); } }; |
In the meantime, we can approach this writing in C++11:
1 2 3 4 5 6 |
struct X { ... private: auto tied() const -> decltype(tie(a, b, c)) { return tie(a, b, c); } }; |
The same can be applied for other comparison operators
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
struct X { int a; double b; string c; bool operator==(const X &rhs) const { return tied() == rhs.tied(); } bool operator< (const X &rhs) const { return orderable() < rhs.orderable(); } private: // C++1y versions auto tied() const { return orderable(); } auto orderable() const { return tie(a, b, c); } // C++11 versions auto tied() const -> decltype(orderable()) { return orderable(); } auto orderable() const -> decltype(tie(a, b, c)) { return tie(a, b, c); }}; }; |
The introduction of orderable() is because the order of members in tie is important for the less operator. Usually tied() can be rerouted on orderable().