[Bug c++/86282] Evaluation order in if constexpr expression seems to be irrelevant for evaluating type traits
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86282 --- Comment #5 from rene.r...@fu-berlin.de --- Many thanks for the explanation and the code examples.
[Bug c++/86282] Evaluation order in if constexpr expression seems to be irrelevant for evaluating type traits
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86282 --- Comment #4 from Jonathan Wakely --- (In reply to rene.rahn from comment #2) > thanks for enlighten me. Before, it wasn't clear to me, that if the nested > version works, the conjunction does not necessarily. The magic "does not get instantiated when false" feature of if-constexpr only applies to the body of the else branch, not to the actual condition being tested. When you have a nested constexpr-if the some_fn(t) expression only occurs inside the body, where it's valid. If it occurs in the condition, it still gets instantiated.
[Bug c++/86282] Evaluation order in if constexpr expression seems to be irrelevant for evaluating type traits
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86282 --- Comment #3 from Jonathan Wakely --- Using std::conjunction: template using has_begin2 = std::bool_constant>; template struct has_nested_begin { // ill-formed unless has_begin is true: static constexpr bool value = has_begin()))>>; }; template int f(T) { if (std::conjunction_v, has_nested_begin>) return 0; return 1; } When has_begin2::value is false, has_nested_begin::value is not needed, so is not instantiated.
[Bug c++/86282] Evaluation order in if constexpr expression seems to be irrelevant for evaluating type traits
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86282 --- Comment #2 from rene.r...@fu-berlin.de --- Hi Jonathan, thanks for enlighten me. Before, it wasn't clear to me, that if the nested version works, the conjunction does not necessarily.
[Bug c++/86282] Evaluation order in if constexpr expression seems to be irrelevant for evaluating type traits
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86282 Jonathan Wakely changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #1 from Jonathan Wakely --- I think GCC's behaviour is correct, as required by the standard. Firstly, if constexpr in main() doesn't work the way you want, because there's nothing dependent (there is no possible version of the function where the condition will be true, so the program is ill-formed). Secondly, if constexpr doesn't short-circuit the instantation of templates and concepts used in the condition, so the entire thing is instantiated even if the actual boolean evaluation short-circuits. That can be solved by using two nested ifs: if constexpr (has_begin) if constexpr (has_begin<...>) Or using std::conjunction, which does avoid instantiating anything that isn't needed (but would require changing your code to use with that concept): https://en.cppreference.com/w/cpp/types/conjunction Here's a working version: #include #include #include template concept bool has_begin = requires (type v) { { std::begin(v) } }; template int f(T p) { if constexpr (has_begin) if constexpr (has_begin>) return 0; return 1; } int main() { f(1); f(std::vector>{}); f(std::vector{}); }