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).
Is 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?
This is exactly what
Access checks are performed as if from a context unrelated to
Tand any of the types inArgs.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With