| 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:
Post a Comment