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 m
Notes: 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.
nameto be public, they all accept it: see demo.namepublic but keep it non-static. You're allowed to access non-static members without an object in (most?) unevaluated contexts.sizeof(S::m)whereSis a class andma non-static member.