lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi] constexpr conversion functions [Was: Detecting whether move semant


From: Greg Chicares
Subject: [lmi] constexpr conversion functions [Was: Detecting whether move semantics actually take place]
Date: Mon, 1 Aug 2022 15:31:25 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.8.0

On 7/23/22 15:41, Vadim Zeitlin wrote:
[...]
>  First, and trivially, you should sprinkle magic constexpr dust all over
> your code, i.e. declare ambiguous conversion operators

I'd like to ask a question about the ambiguous conversion operators only.

> and all the
> functions (equiplausible_construct, equiplausible_assign, c_moveable,
> a_moveable) as constexpr, as this is needed to allow using static_assert<>
> with them. You could also make sandbox_test a compile-only test if you
> replaced all LMI_TEST() in it with static_assert<>s.
[...]
> template<typename T>
> struct ambiguator {
>     constexpr operator T const&();
>     constexpr operator T&&();
> };

If I make all the other changes you suggest, but don't make the two
ambiguous conversion operators 'constexpr', then all the static_assert<>ed
tests pass, and neither gcc nor clang complains. My question is whether
it's still better to make them 'constexpr'. (I will do so anyway; I'm
just trying to understand the rules and their consequences.)

The only reason not to do that is a fear that adding 'constexpr' might
cause them not to work as intended, in some context that I can't imagine.
I searched the entire [class.conv] section of C++20, and it never uses
the word 'constexpr'. At first, that seemed striking: if it's a good idea,
why don't they mention it? But then I figured that they don't mention it
because there's no need: non-constexpr-ness would arise in conversion
functions in the same way as in any other function; and it would arise
in the function-body, but these conversion operators are deliberately
not implemented, so I don't think they can ever fail to satisfy the
requirements to be 'constexpr'.

Then I read [expr.const/8]:

| If an expression of literal class type is used in a context where an
| integral constant expression is required, then that expression is
| contextually implicitly converted (7.3) to an integral or unscoped
| enumeration type and the selected conversion function shall be constexpr.

That alleviates my superstitious fear of adding 'constexpr' to conversion
functions when [class.conv] doesn't mention 'constexpr': [expr.const/8]
gives explicit license for that usage. So why does neither gcc nor clang
complain if the conversion operators aren't 'constexpr'? and are they
wrong not to complain?

Let me put that question in a different way: if I were to report this as
a defect, what reasoning would I present, and how would the maintainers
answer? I would say it's a "manifestly constant-evaluated" conversion,
which makes it "potentially constant evaluated". I suppose they would
retort that
 - this is a conversion rather than an expression; and
 - in fact, it's not a conversion per se--it's just a declaration
     of a conversion operator
and then I might say it's "considered to affect the semantics of the
program" because of [temp.inst/8], to which they'd reply that the
cited paragraph applies only to definitions.

Is that the way such a debate would go? Or is there some simpler or
more fundamental way to decide the theoretical issue? (The practical
issue is easily answered: write 'constexpr' and don't reconsider
that unless a compiler emits a diagnostic.)


reply via email to

[Prev in Thread] Current Thread [Next in Thread]