Friday, January 21, 2022

Digest for comp.lang.c++@googlegroups.com - 6 updates in 1 topic

Bonita Montero <Bonita.Montero@gmail.com>: Jan 21 10:00AM +0100

Am 20.01.2022 um 18:35 schrieb Andrey Tarasevich:
 
 
> What it basically boils down to is that C++20's `consteval` triggers a
> hard error for non-compile-time evaluations, as opposed to `constexpr`,
> which silently opted for run-time evaluation.
 
"if constexpr( )" is always compile-time evaluated.
Juha Nieminen <nospam@thanks.invalid>: Jan 21 09:03AM

>> hard error for non-compile-time evaluations, as opposed to `constexpr`,
>> which silently opted for run-time evaluation.
 
> "if constexpr( )" is always compile-time evaluated.
 
'if constexpr' is not really a constexpr construct. It simply reuses the
keyword.
Bonita Montero <Bonita.Montero@gmail.com>: Jan 21 12:51PM +0100

Am 21.01.2022 um 10:03 schrieb Juha Nieminen:
>>> which silently opted for run-time evaluation.
 
>> "if constexpr( )" is always compile-time evaluated.
 
> 'if constexpr' is not really a constexpr construct. ...
 
Of course, the expression has to be compile-time evaluated.
Andrey Tarasevich <andreytarasevich@hotmail.com>: Jan 21 10:19AM -0800

On 1/21/2022 1:00 AM, Bonita Montero wrote:
>> hard error for non-compile-time evaluations, as opposed to
>> `constexpr`, which silently opted for run-time evaluation.
 
> "if constexpr( )" is always compile-time evaluated.
 
`if constexpr` can be used to test compile-time nature of an expression,
but it can only be done "from the outside" of that expression. I don't
immediately see how would one go about using `if constexpr` for function
argument verification, especially considering that that verification has
to be injected after template argument deduction.
 
In order to achieve that injection they used a well-known technique,
which is as old as the world itself. They implemented an intermediate
pass-through `Checker` class, which performs the necessary checks in its
constructor. Nothing new here.
 
However, previously we would only be able generate run-time errors
(assertion failures) from inside that constructor. That's how this
technique has been used for ages.
 
They show that now, by declaring that constructor as `consteval`, one
can also generate compile-time errors (!) from inside that constructor.
 
Of course, by doing so one's restricting oneself to compile-time
arguments exclusively. But apparently in their application they don't
mind that. And, if I'm mot mistaken, one can get the best of both worlds
by branching on `if (std::is_constant_evaluated)`/`if consteval`.
 
--
Best regards,
Andrey Tarasevich
Bonita Montero <Bonita.Montero@gmail.com>: Jan 21 07:51PM +0100

Am 21.01.2022 um 19:19 schrieb Andrey Tarasevich:
> arguments exclusively. But apparently in their application they don't
> mind that. And, if I'm mot mistaken, one can get the best of both worlds
> by branching on `if (std::is_constant_evaluated)`/`if consteval`.
 
You can virtually even check parameters with it:
 
template<bool B>
void f( bool_constabt<B> x )
{
if constexpr( B )
...
}
 
I use it very often for templated parameters, sometimes
to check their type-properties, f.e. if they're integral.
Andrey Tarasevich <andreytarasevich@hotmail.com>: Jan 21 12:03PM -0800

On 1/21/2022 10:51 AM, Bonita Montero wrote:
> }
 
> I use it very often for templated parameters, sometimes
> to check their type-properties, f.e. if they're integral.
 
You are checking a template argument - an entity that is inherently
compile-time. "There is no renown in that." Many techniques are
available for checking template arguments at compile time even in C++98.
 
Meanwhile, they want to check regular function arguments (!) at compile
time (under assumption that they are supplied with compile-time
arguments, of course). That is a wholly different story.
 
And they also want to be able to check template arguments based on such
regular function arguments.
 
E.g.
 
#include <string_view>
#include <type_traits>
 
template <typename T>
struct Checker {
consteval Checker(const char* fmt)
{
if (fmt == std::string_view{ "int" } &&
std::is_same_v<T, int>)
return;
 
if (fmt == std::string_view{ "double" } &&
std::is_same_v<T, double>)
return;
 
throw;
}
};
 
template <typename T>
void fmt(std::type_identity_t<Checker<T>> checked, T) {}
 
int main()
{
fmt("int", 42); // OK
fmt("double", 1.23); // OK
fmt("int", "foo"); // Compile error
}
 
--
Best regards,
Andrey Tarasevich
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: