c++c++-conceptsc++-templates

Why can't C++ concepts use a simple requirement to check if a nested type exists?


template <typename T>
concept HasInner = requires { T::inner; };

void foo(HasInner auto x) { return; }
struct Test { using inner = int; };

int main()
{
    foo(Test());
}

Why can't this code be compiled? Is T::inner; not a valid expression?

I know concept HasInner = requires { typename T::inner; }; is ok. But I want know why the first one is not ok.

Thank you, everyone. I got it.

T::inner is invalid, because of a type name like int is not a expression. So, HasInner is satisfied when T::inner is a expression.

struct Test { constexpr int static inner = 1; };
int main()
{
    foo(Test()); // This code can be compiled correctly.
}

Solution

  • I know concept HasInner = requires { typename T::inner; }; is ok. But I want know why the first one is not ok.

    Because requires{ T::inner; } expects T::inner to not be a type (but rather a variable or a function). I'm not sure what answer you expected.

    It wouldn't be very useful to make T::inner accept both types and non-types.