If constexpr and require-expression for checking special rules

Say, given C ++ 17 if constexpr and Concepts TS (for example, in recent versions of gcc), we would like to check if the type in the template function has a nested type:

 #include <iostream> struct Foo { using Bar = int; }; template<typename T> void doSmth(T) { if constexpr (requires { typename T::Bar; }) std::cout << "has nested! " << typename T::Bar {} << std::endl; else std::cout << "no nested!" << std::endl; } int main() { doSmth(Foo {}); //doSmth(0); } 

The documentation for concepts is limited, so I could be wrong, but it seems like it (and a live example is on Wandbox ).

Now consider what should happen when uncommenting another doSmth call. It seems reasonable to expect the require condition to evaluate to false , and the else if constexpr branch if constexpr be accepted. Contrary to this, gcc makes this a tough mistake:

 prog.cc: In instantiation of 'void doSmth(T) [with T = int]': prog.cc:17:13: required from here prog.cc:8:5: error: 'int' is not a class, struct, or union type if constexpr (requires { typename T::Bar; }) ^~ 

Is this a bug in gcc or is this the intended behavior?

+5
source share
1 answer

Concept 3 (β€œAllow Expression Queries in More Contexts”) was assigned WP status in June. And judging by the current views [expr.prim.req] , in particular p6:

Substitution of template arguments into a requirement expression can lead to the formation of invalid types or expressions in its requirements or to violation of the semantic restrictions of these requirements. In such cases, expression-expression evaluates to false ; this does not lead to poor program formation.

I would say that your code is in order and GCC did not execute the solution to problem 3 properly.

+3
source

Source: https://habr.com/ru/post/1273151/


All Articles