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.1
the 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.