is_constructible 和 is_destructible 不受朋友声明的影响
is_constructible and is_destructible unaffected by friend declarations
Clang 和 GCC 在评估 std::is_constructible
和 std::is_destructible
时似乎不遵守 friend
声明。
关于`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
如何处理访问检查,但是访问修饰符 do 通常会影响 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 in Args
.
说。 "A friend of T
" 根据定义不是 "unrelated to T
"。
"immediate context"是一个术语,但无论如何这句话是在谈论假设变量定义的直接上下文,而不是使用is_constructible
。
使 is_constructible
检查依赖于上下文是疯狂的;这意味着相同的类型 is_constructible<T, Args...>
在不同的上下文中具有不同的基础 类。
Clang 和 GCC 在评估 std::is_constructible
和 std::is_destructible
时似乎不遵守 friend
声明。
关于`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
如何处理访问检查,但是访问修饰符 do 通常会影响 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
.
说。 "A friend of T
" 根据定义不是 "unrelated to T
"。
"immediate context"是一个术语,但无论如何这句话是在谈论假设变量定义的直接上下文,而不是使用is_constructible
。
使 is_constructible
检查依赖于上下文是疯狂的;这意味着相同的类型 is_constructible<T, Args...>
在不同的上下文中具有不同的基础 类。