I have a C 20 concept, intended to allow a CRTP interface to prevent the templated type from exposing a static member publicly:
template< typename T >
concept BuildInaccessible = !requires
{
T::build ( Ent {} );
};
I then use it like this:
static_assert ( BuildInaccessible< T >, "... must declare ... as a non-public static member" );
- With
MSVC 17.4.1the constraint works perfectly. - With
Clang 15, the constraint seems to succeed even if the member is protected. - With
GCC 12, it also seems to succeed when it should fail.
Am I trying to do something non-standard, or do Clang and GCC not support this in these versions?
With MSVC, the static assert succeeds with the first class, and fails with the second:
struct SomePrefab : CRTP::Prefab< SomePrefab >
{
protected:
static void build ( Ent target );
};
struct SomePrefab : CRTP::Prefab< SomePrefab >
{
public:
static void build ( Ent target );
};
Whereas GCC and Clang always succeed at finding the member, making the protected member still fail the static assert.
CodePudding user response:
Concepts are completely blind to accessibility (public/private). They are always public and therefore can only access things that are publicly accessible. They therefore cannot check to see if something is declared non-publicly. BuildInaccessible<T> will be just as true for a class T which has no declaration of a build member function as for one which declares it private.
Also, it's not a good idea to be this controlling over a conceptualized interface. If a user wants to declare it publicly for whatever reason, that's on them.
