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?
>
> > 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