Question Details

No question body available.

Tags

c++ visual-c++ c++-concepts requires-expression

Answers (2)

August 16, 2025 Score: 3 Rep: 36,828 Quality: Medium Completeness: 80%

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:

  1. (for data members only, not member functions) When used in unevaluated operands.
    struct S
    {
       int m;
       static const std::sizet 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.

August 16, 2025 Score: 2 Rep: 3,497 Quality: Low Completeness: 40%

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 concept HasName = requires { &T::name; };

static_assert(HasName);

This is rejected by all three compilers. And, all three accept it, if name's access is public.