I'm trying to implement lexicographic comparison for std::tuple. I know the standard provides this. I'm doing it as a TMP exercise. I can't see why the code below doesn't work. Can anyone point me in the right direction?
I know the code below assumes operands of the same type. I am happy making this as a simplifying assumption.
I've looked at the VC++ 2013 and GCC 4.7 implementations. They both use non-standard helper classes to get the tail (i.e. all but the left-most element) from a tuple. I'd like to solve the problem with as little scaffolding as possible. Is it possible to do tuple comparison without something like get_tail?
#include <iostream>
#include <string>
#include <tuple>
// Pseudo-recursion.
template<class tupleT,std::size_t N>
struct tuple_ops {
static bool less(const tupleT& x,const tupleT& y) {
return std::get<N-1>(x) < std::get<N-1>(y) ||
( !(std::get<N-1>(y) < std::get<N-1>(x)) &&
tuple_ops<tupleT,N-1>::less(x,y) );
}
};
// Base Case.
template<class tupleT>
struct tuple_ops<tupleT,1> {
static bool less(const tupleT& x,const tupleT& y) {
return std::get<0>(x) < std::get<0>(y);
}
};
// Convenience wrapper.
template<class... T>
bool operator<(const std::tuple<T...>& x,const std::tuple<T...>& y) {
return tuple_ops<decltype(x),sizeof...(T)>::less(x,y);
}
int main() {
using namespace std;
auto tup0 = make_tuple(3.14,string("foo"),2.71);
auto tup1 = make_tuple(4.01,string("foo"),2.01);
auto tup2 = make_tuple(1,string("bar"),5);
auto tup3 = make_tuple(1,string("foo"),5);
cout << (::operator<(tup0,tup1)) << ' '
<< (::operator<(tup2,tup3)) << ' '
<< !(::operator<(tup1,tup0)) << ' '
<< !(::operator<(tup3,tup2)) << ' ';
return 0;
}
Output: 0 1 0 1
Correct output would be: 1 1 1 1
Thanks in advance.
Aucun commentaire:
Enregistrer un commentaire