operator> in containers, tuple, and eventually optional

110 views
Skip to first unread message

Tony V E

unread,
Feb 15, 2013, 1:46:17 PM2/15/13
to std-dis...@isocpp.org
IIUC, operator>() for containers and tuple, is defined via operator<()
and NOT defined via operator>() of the underlying value type. ie


#include <tuple>

struct MyType
{
bool operator<(MyType const &) const { return false; }
bool operator>(MyType const &) const { return true; }
};

int main()
{
std::tuple<MyType> t, u;

return t > u;
}

returns 0, not 1.

Is this expected? Or a defect?

If expected, would you apply this to the proposed std::optional<>?


int main()
{
std::optional<MyType> t, u;

return t > u;
}

I would expect optional<MyType> to work as much like MyType as
possible, but that doesn't follow the pattern of containers and tuple.
Not that containers or tuple are the same as optional, but there is
similarity.

Tony

Max Skvortsov

unread,
Feb 17, 2013, 8:49:50 PM2/17/13
to std-dis...@isocpp.org
MyType is unordered because a<b and b<a both false, where a and b of MyType.
As tuple operator < implemented in terms of lexicographical compare, returning 0 is expected.

суббота, 16 февраля 2013 г., 3:46:17 UTC+9 пользователь Tony VE написал:

Daniel Krügler

unread,
Feb 18, 2013, 6:23:52 PM2/18/13
to std-dis...@isocpp.org
2013/2/15 Tony V E <tvan...@gmail.com>:
> IIUC, operator>() for containers and tuple, is defined via operator<()
> and NOT defined via operator>() of the underlying value type. ie
>
> #include <tuple>
>
> struct MyType
> {
> bool operator<(MyType const &) const { return false; }
> bool operator>(MyType const &) const { return true; }
> };
>
> int main()
> {
> std::tuple<MyType> t, u;
>
> return t > u;
> }
>
> returns 0, not 1.
>
> Is this expected? Or a defect?

I don't see any reason for a defect. In fact, the library explicitly
gives wording that makes this choices intentional, see [operators]
p10:

"In this library, whenever a declaration is provided for an
operator!=, operator>, operator>=, or operator<=,
and requirements and semantics are not explicitly provided, the
requirements and semantics are as specified
in this Clause."

Basically all newer class templates have decided to make this
explicit, only some "older" ones (like std::reverse_iterator) don't.

> If expected, would you apply this to the proposed std::optional<>?

Yes.

> int main()
> {
> std::optional<MyType> t, u;
>
> return t > u;
> }
>
> I would expect optional<MyType> to work as much like MyType as
> possible, but that doesn't follow the pattern of containers and tuple.

A similar example is the std::chrono::duration template, whose
comparison functions are solely defined in terms of == and <. This
harmonizes with [operators] p10 and should be the recommended way for
future types, IMO.

> Not that containers or tuple are the same as optional, but there is
> similarity.

I think the similarity is quite strong.

- Daniel

Tony V E

unread,
Feb 18, 2013, 8:41:02 PM2/18/13
to std-dis...@isocpp.org
:-(

I feel that if/when optional<T> deviates from T, it is wrong.
optional<T> should be "T if not null" whenever possible.

I see the reasoning for tuple<> et al, but I'm not comfortable
applying the same rules to optional. But I guess that is more for
std-proposal than std-discussion.

Tony

corn...@google.com

unread,
Mar 6, 2013, 7:11:30 AM3/6/13
to std-dis...@isocpp.org


On Friday, February 15, 2013 7:46:17 PM UTC+1, Tony VE wrote:
IIUC, operator>() for containers and tuple, is defined via operator<()
and NOT defined via operator>() of the underlying value type.  ie


#include <tuple>

struct MyType
{
    bool operator<(MyType const &) const { return false; }
    bool operator>(MyType const &) const { return true; }
};

If your comparison operators do not create a valid strict weak ordering or are inconsistent with each other, you're going to have a bad time. (Your operator > violates irreflexivity because a > b && b > a.) If they create the order and are consistent with each other, it doesn't matter which one is used to define the lifted comparison.

Tony V E

unread,
Mar 6, 2013, 2:13:53 PM3/6/13
to std-dis...@isocpp.org
I completely agree. I don't tend to write them; however, we allow
inconsistent operators.

Now that I know the stance for containers, it is more of a question
for std::optional, and a discussion for the std-proposal list. Which
I will get back to some day...

Tony
Reply all
Reply to author
Forward
0 new messages