C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Function only accepts parameter that will persist

From: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Date: Fri, 3 May 2024 11:52:16 +0100
On Thu, May 2, 2024 at 4:20 PM Thiago Macieira wrote:
>
> > Anyone got any ideas to get it to recognise 'x' as a compile-time
> > constant? Or would we need a change to the core language?
>
> Use __builtin_constant_p(*x). So yes, you need compiler support.


Perhaps we could talk about a core language change to cut out all the
ambiguity and implementation-dependant behaviour here?

The first complication is as follows: In the C++ programming language,
all literals are Rvalues, except for string literals which are
Lvalues. And so this is why the following won't compile:

    bool Func( char const (&&arg)[6] )
    {
        if consteval { return true; }
        return false;
    }

    int main(void)
    {
        Func("Hello"); // can't bind Rvalue ref
    }

So let's forget about string literals for a moment, and instead work
with compound literals. So for example if we have:

    struct Frog { int a; double b; char *p; };

    constexpr bool Func(Frog const &&f)
    {
        if consteval { return true; }
        return false;
    }

And then we call it as follows:

    int main(void)
    {
        cout << Func( Frog{-1,3.14,nullptr} ) << endl;
    }

We could make a new rule in C++26 something like:
    Rule No. 1: If a function is marked as 'constexpr' or
'consteval', and if any of its parameters are
Rvalue-references-to-const, and if said function is invoked in a
constant-evaluated context (i.e. std::is_constant_evaluated() returns
true), then the argument (and in the case of pointers and references
-- the referred object also), must be a compile-time constant.

Next we have to talk about string literals. Normally a string literal
is an Lvalue, however we could make a new rule as follows:
    Rule No. 2: A string literal is an Lvalue of type "char[N]", and
normally you would need to use "std::move" to bind an Rvalue reference
to it, however the new rule is that a string literal can implicitly
convert to "char const (&&)[N]".

How does that all sound? Would it help us to implement a new class,
std::efficient_string, that only copies the string if it needs to?

Received on 2024-05-03 10:52:29