Is there a method to decide whether something can be constexpr evaluated, and use the result as a constexpr boolean? My simplified use case is as follows:
template <typename base> class derived {     template<size_t size>     void do_stuff() { (...) }      void do_stuff(size_t size) { (...) } public:     void execute()     {         if constexpr(is_constexpr(base::get_data())         {             do_stuff<base::get_data()>();         }         else         {             do_stuff(base::get_data());         }     } }   My target is C++2a.
I found the following reddit thread, but I'm not a big fan of the macros. https://www.reddit.com/r/cpp/comments/7c208c/is_constexpr_a_macro_that_check_if_an_expression/
If you pass a non-constexpr argument to the PlusOne function, the compiler can't evaluate it at compile-time, and it will simply be a normal run-time function. Hint: "The constexpr specifier declares that it is possible to evaluate the value of the function or variable at compile time."
The easiest way to check whether a function (e.g., foo ) is constexpr is to assign its return value to a constexpr as below: constexpr auto i = foo(); if the returned value is not constexpr compilation will fail.
constexpr functions will be evaluated at compile time when all its arguments are constant expressions and the result is used in a constant expression as well.
Constexpr ifIf the value is true, then statement-false is discarded (if present), otherwise, statement-true is discarded.
Here's another solution, which is more generic (applicable to any expression, without defining a separate template each time).
This solution leverages that (1) lambda expressions can be constexpr as of C++17 (2) the type of a captureless lambda is default constructible as of C++20.
The idea is, the overload that returns true is selected when and only when Lambda{}() can appear within a template argument, which effectively requires the lambda invocation to be a constant expression.
template<class Lambda, int=(Lambda{}(), 0)> constexpr bool is_constexpr(Lambda) { return true; } constexpr bool is_constexpr(...) { return false; }  template <typename base> class derived {     // ...      void execute()     {         if constexpr(is_constexpr([]{ base::get_data(); }))             do_stuff<base::get_data()>();         else             do_stuff(base::get_data());     } } 
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With