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

时间:2016-09-12 05:13:57

标签: c++ c++11 gcc clang access-modifiers

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

关于`is_constructible,Coliru compiles it without error

  

执行访问检查就好像来自与T无关的上下文和Args中的任何类型。只考虑变量定义的直接上下文的有效性。

(该网站没有解释is_destructible如何处理访问权限检查,但访问修饰符执行一般会影响is_destructible的行为,所以我&#39 ; d期望它的工作方式与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;
        }
};

...但是{{3}}(使用GCC或Clang)。

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

1 个答案:

答案 0 :(得分:4)

这正是

  

执行访问检查就好像来自与T无关的上下文   Args中的任何类型。

说。 &#34; T&#34;的朋友根据定义,&#34;与T&#34;无关。

"immediate context"是一个艺术术语,但无论如何,句子是在谈论假设变量定义的直接背景,而不是is_constructible的使用。

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