This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD Concepts status.

928. Wrong concepts used for tuple's comparison operators

Section: 22.4.9 [tuple.rel] Status: NAD Concepts Submitter: Joe Gottman Opened: 2008-10-28 Last modified: 2016-01-28

Priority: Not Prioritized

View other active issues in [tuple.rel].

View all other issues in [tuple.rel].

View all issues with NAD Concepts status.

Discussion:

In the latest working draft for C++0x, tuple's operator== and operator< are declared as

template<class... TTypes, class... UTypes> 
  requires EqualityComparable<TTypes, UTypes>... 
  bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);

and

template<class... TTypes, class... UTypes> 
  requires LessThanComparable<TTypes, UTypes>... 
  bool operator<(const tuple<TTypes...>& t, const tuple<UTypes...>& u);

But the concepts EqualityComparable and LessThanComparable only take one parameter, not two. Also, even if LessThanComparable could take two parameters, the definition of tuple::operator<() should also require

LessThanComparable<UTypes, TTypes>... // (note the order) 

since the algorithm for tuple::operator< is the following (pseudo-code)

for (size_t N = 0; N < sizeof...(TTypes); ++N) { 
    if (get<N>(t) < get<N>(u) return true; 
    else if ((get<N>(u) < get<N>(t)) return false; 
} 

return false; 

Similar problems hold for tuples's other comparison operators.

[ Post Summit: ]

Recommend Tentatively Ready.

Proposed resolution:

In 22.4.1 [tuple.general] and 22.4.9 [tuple.rel] change:

template<class... TTypes, class... UTypes>
  requires EqualityComparableHasEqualTo<TTypes, UTypes>...
  bool operator==(const tuple<TTypes...>&, const tuple<UTypes...>&);

template<class... TTypes, class... UTypes>
  requires LessThanComparableHasLess<TTypes, UTypes>... && HasLess<UTypes, TTypes>...
  bool operator<(const tuple<TTypes...>&, const tuple<UTypes...>&);

template<class... TTypes, class... UTypes>
  requires EqualityComparableHasEqualTo<TTypes, UTypes>...
  bool operator!=(const tuple<TTypes...>&, const tuple<UTypes...>&);

template<class... TTypes, class... UTypes>
  requires LessThanComparableHasLess<UTTypes, TUTypes>... && HasLess<UTypes, TTypes>...
  bool operator>(const tuple<TTypes...>&, const tuple<UTypes...>&);

template<class... TTypes, class... UTypes>
  requires LessThanComparableHasLess<UTTypes, TUTypes>... && HasLess<UTypes, TTypes>...
  bool operator<=(const tuple<TTypes...>&, const tuple<UTypes...>&);

template<class... TTypes, class... UTypes>
  requires LessThanComparableHasLess<TTypes, UTypes>... && HasLess<UTypes, TTypes>...
  bool operator>=(const tuple<TTypes...>&, const tuple<UTypes...>&);