This paper:
http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0515r0.pdf
proposes a new operator, "operator <=>", to do 3-way comparisons.
It gives this example as a potential implementation of an operator<=>:
std::strong_ordering operator<=> (const TotallyOrdered & that) const
{
if (auto cmp = (Base&) (*this) <=> (Base&)that; cmp != 0) return cmp;
if (auto cmp = last_name <=> that.last_name; cmp != 0) return cmp;
if (auto cmp = first_name <=> that.first_name; cmp != 0) return cmp;
return tax_id <=> that.tax_id;
}
A comparable operator== would be written this way:
bool operator== (const TotallyOrdered & that) const
{
return (Base&) (*this) == (Base&)that
&& last_name == that.last_name
&& first_name == that.first_name
&& tax_id == that.tax_id;
}
So, my suggestion is to add semantics for "&&" on the "strong_ordering" type (and "weak_ordering" which is works effectively the same way) such that
a && b
evaluates to "a", without evaluating "b", if "a != 0". Otherwise, "b" is evaluated, and its value is the value of the expression.
This cannot be done with regular overloading, as there is significant value in the shortcut behavior.
I don't like the idea of adding special semantics to an existing operator that when applied to specific types. If we want to add an operator that has works like this on all types (which are comparable to 0), that's one thing. Or if we want to add a way for people to write such conditional statements, that's one thing.
On Monday, 4 December 2017 14:48:21 PST charle...@gmail.com wrote:
> So, my suggestion is to add semantics for "&&" on the "strong_ordering"
> type (and "weak_ordering" which is works effectively the same way) such that
> a && b
> evaluates to "a", without evaluating "b", if "a != 0".
So you want to change && when left and right are ints?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/0a442019-a580-4d39-80ed-0890e2ceb3e8%40isocpp.org.
I don't like the idea of adding special semantics to an existing operator that when applied to specific types. If we want to add an operator that has works like this on all types (which are comparable to 0), that's one thing. Or if we want to add a way for people to write such conditional statements, that's one thing.It already has special semantics on "bool".
Giving the built-in && a return type other than "bool" for some operands seems very surprising to me.Perhaps it's time to consider the GNU binary conditional operator again?return a.x <=> b.x ?: a.y <=> b.y ?: a.z <=> b.z;
Giving the built-in && a return type other than "bool" for some operands seems very surprising to me.Perhaps it's time to consider the GNU binary conditional operator again?return a.x <=> b.x ?: a.y <=> b.y ?: a.z <=> b.z;... seems to be exactly what we want (assuming that contextual conversion of the comparison category types to bool actually works, which I've been assuming is the case but haven't checked...).
For heterogeneous comparisons, yes, you'll need to write that.I don't like the idea of adding special semantics to an existing operator that when applied to specific types. If we want to add an operator that has works like this on all types (which are comparable to 0), that's one thing. Or if we want to add a way for people to write such conditional statements, that's one thing.It already has special semantics on "bool".Sure, and wouldn't it be so much better if we could get those special semantics on our types that are boolean-like?
On Monday, 4 December 2017 16:26:20 PST charle...@gmail.com wrote:
> On Monday, December 4, 2017 at 4:05:51 PM UTC-8, Thiago Macieira wrote:
> > On Monday, 4 December 2017 14:48:21 PST charle...@gmail.com <javascript:>
> >
> > wrote:
> > > So, my suggestion is to add semantics for "&&" on the "strong_ordering"
> > > type (and "weak_ordering" which is works effectively the same way) such
> >
> > that
> >
> > > a && b
> > > evaluates to "a", without evaluating "b", if "a != 0".
> >
> > So you want to change && when left and right are ints?
>
> No. Only if they're both "strong_ordering" or both "weak_ordering".
And what are strong_ordering or weak_ordering?
If they are enums, then they behave like int. Special-casing a type seems like
a bad idea.
If they are a class, then you can collect references to all types and execute
the comparison at the moemnt of conversion to int.
> These
> have semantics that allow "!= 0" to mean something. It's probably
> equivalent to "== <some enumerator>" but it's usually expressed that way in
> the paper (e.g. the example I give). I am not suggesting changing the
> semantics of anything that already exists in the standard.
Sorry, but you kind of are.
For heterogeneous comparisons, yes, you'll need to write that.I don't like the idea of adding special semantics to an existing operator that when applied to specific types. If we want to add an operator that has works like this on all types (which are comparable to 0), that's one thing. Or if we want to add a way for people to write such conditional statements, that's one thing.It already has special semantics on "bool".Sure, and wouldn't it be so much better if we could get those special semantics on our types that are boolean-like?Yes it would, of course. But that would be a big change. I'm proposing a small change, and it would not hamper the bigger change you're suggesting.
On Monday, 4 December 2017 18:45:05 PST charle...@gmail.com wrote:
> > If they are a class, then you can collect references to all types and
> > execute
> > the comparison at the moemnt of conversion to int.
>
> I do not understand what you mean by this. How do you avoid computing the
> class value using shortcut semantics?
> e.g.
> if(a <=> b && expensiveToCompute() <=> c) {
> }
> how do you avoid running "expensiveToCompute()"? This might even be a
> correctness issue, it could be "crashIfANotEqualToB()"
By delaying the evaluation.
Instead of operator<=> performing the comparison, it returns an object that
has a reference to the left and right sides.
You should write a paper that provides for a way to create custom operator&&
and operator|| that allow for short-circuiting. That would be useful in other
cases besides operator<=>.
Hyman's proposal was also discussed here 3 years ago: