Both Clang and GCC refuse to compile this but MSVC doesn't.
class Foo {
int name;
};
template <class T>
concept HasName = requires { T::name; };
static_assert(HasName<Foo>);
MSVC only checks if the name exists, but it doesn't enforce access restrictions (i.e., private), and allows member access from without a class instance/object.
Addition from comments below:
Making name public allows to code to compile. But name is a non-static member, so why it is allowed to refer to it as T::name inside the requires ?
As already mentioned, MSVC is wrong to accept the code since name member is private.
However - you also seems to be interested (based on the comments) to know why making it public causes the code to be valid (and accepted by the major compilers - see demo).
Specifically since name is a non-static member why is it OK to use it as T::name in the requires expression.
The reason is that in an unevaluated context you can use this syntax to refer to non-static members.
This is mentioned in item 3 of the Usage section in this cppreference page:
- (for data members only, not member functions) When used in unevaluated operands.
struct S { int m; static const std::size_t sz = sizeof m; // OK: m in unevaluated operand }; std::size_t j = sizeof(S::m + 42); // OK: even though there is no "this" object for mNotes: such uses are allowed via the resolution of CWG issue 613 in N2253, which is treated as a change in C++11 by some compilers (e.g. clang).
(emphasis is mine)
As you can see S::m is valid inside sizeof (even though m is non-static) because it is an unevaluated context, just like in your case.
MSVC doesn't take into account name's access, which is an obvious bug in the compiler. Work it around by prepending an &:
class Foo {
int name;
};
template <class T>
concept HasName = requires { &T::name; };
static_assert(HasName<Foo>);
This is rejected by all three compilers. And, all three accept it, if name's access is public.
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