关于`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.
(该网站没有解释is_destructible如何处理访问检查,但访问修饰符确实会影响is_destructible的行为,因此我希望它的工作方式与is_constructible相同.)
因此,在我看来,这段代码不应该编译,因为在检查的直接上下文中,构造函数和析构函数是可用的,如局部变量实例化所证明的:
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; } };
……但是Coliru compiles it without error(使用GCC或Clang).
这是两个编译器中的错误(或至少是不合格),或者cppreference.com是否歪曲了标准,还是我误解了cppreference.com的声明?
解决方法
Access checks are performed as if from a context unrelated to
T
and
any of the types inArgs
.
说.根据定义,“T的朋友”不“与T无关”.
“immediate context”是一个艺术术语,但无论如何,句子是在谈论假设变量定义的直接上下文,而不是使用is_constructible.
使is_constructible检查依赖于上下文是疯狂的;这意味着相同的类型is_constructible< T,Args ...>在不同的上下文中具有不同的基类.