is_constructible和is_destructible不受朋友声明的影响

Kyl*_*and 8 c++ gcc access-modifiers clang c++11

friend在评估std::is_constructible和评估时,Clang和GCC似乎不尊重声明std::is_destructible.

关于`is_constructible,cppreference.com说:

从与T无关的上下文和Args中的任何类型执行访问检查.仅考虑变量定义的直接上下文的有效性.

(该网站没有解释如何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;
        }
};
Run Code Online (Sandbox Code Playgroud)

...但Coliru编译它没有错误(使用GCC或Clang).

这是两个编译器中的错误(或至少是不合格),或者cppreference.com是否歪曲了标准,还是我误解了cppreference.com的声明?

T.C*_*.C. 5

这正是

访问检查的执行就像是从与T和 中的任何类型无关的上下文中执行Args

说。“”的朋友T根据定义与“无关T”。

“直接上下文”是一个艺术术语,但无论如何,该句子是在谈论假设变量定义的直接上下文,而不是使用is_constructible.

使is_constructible检查依赖于上下文将是疯狂的;这意味着相同的类型 ,is_constructible<T, Args...>在不同的上下文中具有不同的基类。