Kyle Strand Kyle Strand - 2 months ago 14
C++ Question

is_constructible and is_destructible unaffected by friend declarations

Clang and GCC appear not to honor

friend
declarations when evaluating
std::is_constructible
and
std::is_destructible
.

Regarding `is_constructible, cppreference.com says:


Access checks are performed as if from a context unrelated to T and any of the types in Args. Only the validity of the immediate context of the variable definition is considered.


(The site doesn't explain how
is_destructible
deals with access checks, but access modifiers do affect the behavior of
is_destructible
in general, so I'd expect it to work the same way as
is_constructible
.)

Therefore, it seems to me that this code should not compile, since in the immediate context of the check the constructor and destructor are available, as evidenced by the local variable instantiation:

class Private
{
Private() {}
~Private() {}

friend class Friend;
};

class Friend
{
public:
Friend()
{
// Both of these should fire, but they do not.
static_assert(
!std::is_constructible<Private>::value,
"the constructor is public");
static_assert(
!std::is_destructible<Private>::value,
"the destructor is public");
// There is no error here.
Private p;
}
};


...but Coliru compiles it without error (using either GCC or Clang).

It's this a bug (or at least a nonconformity) in both compilers, or is cppreference.com misrepresenting the standard, or am I misunderstanding cppreference.com's statement?

Answer

This is exactly what

Access checks are performed as if from a context unrelated to T and any of the types in Args.

says. "A friend of T" is by definition not "unrelated to T".

"immediate context" is a term of art, but in any event the sentence is talking about the immediate context of the hypothetical variable definition, not the use of is_constructible.

It would be madness to make the is_constructible check context-dependent; that would mean that the same type, is_constructible<T, Args...>, has different base classes in different contexts.