I came to know that for a class X with a member function named func, the c++ standard doesn't allow us to write decltype(X::func). Thus I expected the below given program to produce an error saying something like invalid use of non-static member function. But to my surprise, the program compiles with all 3 compilers.
#include <iostream>
#include <type_traits>
#include <concepts>
template < typename T >
concept test = std::same_as <decltype(T::func), int(int) >;
struct D
{
int func(int);
};
int main()
{
std::cout << test<D>;
}
The above program is compiled by all 3 compilers. By looking at [expr.prim.id] it seems the program should be ill-formed and a diagnostic should be emitted. But none of the compilers provide any error. So, does the use of concept in a way shown in the program make the program well-formed or is it still ill-formed and are all compilers wrong?
The program is well-formed as explained below. From [temp.constr.normal]:
(emphasis mine)
Note the emphasis on the last sentence. In particular, it is about parameter mapping. That is, if the parameter mapping results in an invalid type, then only the program will be IFNDR.
But in your given example, the parameter mapping is
T ->decltype(T::func)which is not in itself an invalid type. Thus, the above quoted reference is not satisfied.Now, from [temp.constr.atomic#3]:
(emphasis mine)
And since the substitution of the template argument
Dresults in an invalid constructdecltype(D::func), the given constraint is not satisfied(meaning it isfalse).Thus, all compilers are correct in accepting the program and outputting
0.