This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [v3] complex comparison operators
> > So, I went looking for other areas in the library that might benefit
> > from constexpr comparison operators.
> >
> > Audit rubric:
> > 1) if static constexpr function can return it
> > 2) if some other class can contain it as a static constexpr data
> > 3) has one of operator ==, !=, >, >=, <, <=
> > 4) implementation of comparison operators calls only constexpr
> > functions
> >
> > This turns up std::complex operators == and != as candidates.
>
> good catch. They should be marked constexpr. Since we now have the
> close that `constexpr' is silently ignored if the function template
> specialization
> fails to be constexpr, that would be hamless.
Done.
Isn't this exactly the reason the primary template for complex should
be marked constexpr in the same way that the specializations are?
For user-defined literal types, it's a win! Then these types could
actually use the primary template, if desired, and still take advantage
of constexpr'd goodness.
For user-defined types that aren't iteral, then no worries. Everything
works as per usual, with the silent ignoring. If the user then decides
to get cocky and tries to apply constexpr, such as a constexpr variable
of type complex<user_defined_type>, then the compiler will yelp. This
seems highly normal to me, and desired behavior.
FYI function templates real and imag in <complex> can also be constexpr.
Will mark as such.
> >
> > Close:
> > 1. tuple, pair, and <random>'s engines have operator ==, but no
> > constexpr construction.
>
> That would have required that every template argument of pair<> be a
> literal type (at least that was the requirement some time ago, I do
> not know whether that changed.)
Yes, indeed.
I see a big advantage in opportunisticly marking tuple and pair
non-default constructors constexpr, since these
types are often used as member data in user-defined types.
Then they could be used as member data in user-defined literal types.
Win, reuse.
> Makeing the primary template a literal type would have imposed a
> hardship on which type can be used to it -- e.g. the template
> argument would have to be a literal type.
There is no hardship here. No functionality is lost, only gained.
Non-literal types can still use the primary template, they just won't
be able to take advantage of constexpr. If users try to do the wrong
thing, well then the compiler will complain. As long as they are not
doing something the underlying type doesn't support, the program is
well formed.
So be it. This is expected.
User-defined literal types, on the other hand, will now be able to use
the primary template. And get all the advantages that only the
specializations enjoy currently.
Your position/thinking on this is forcing people to use specializations
for complex if they want to use constexpr. Admittedly, this is not as
important for complex as it is for pair/tuple. But you get my drift,
hopefully.
-benjamin