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

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

关于`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 in Args.

说.根据定义,“T的朋友”不“与T无关”.

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

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

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...