【问题标题】:is_constructible and is_destructible unaffected by friend declarationsis_constructible 和 is_destructible 不受友元声明的影响
【发布时间】:2017-01-19 12:01:43
【问题描述】:

在评估 std::is_constructiblestd::is_destructible 时,Clang 和 GCC 似乎不遵守 friend 声明。

关于`is_constructible,cppreference.com says:

访问检查是从与 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;
        }
};

...但是 Coliru compiles it without error(使用 GCC 或 Clang)。

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

【问题讨论】:

  • 这基本上是直接来自标准的引用(更改了几个词)。另外,这不是“直接上下文”的意思。
  • @T.C.我不知道标准语言中的“即时上下文”是什么意思,但令我非常惊讶的是is_constructible 的结果并没有告诉你对象是否可以在非常下一行代码中构造 i>.
  • 另一种选择是同一类型 (is_constructible&lt;T, Args..&gt;)具有不同的基类,具体取决于使用的位置。
  • @T.C.好的,我明白了我想象的版本是如何无法实现的,而且在类型系统方面也有些荒谬。我想在阅读this 之后我对“直接上下文”的理解更好一些,但我当然不觉得这是一个直观易懂的短语。

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


【解决方案1】:

原来是这样

访问检查是在与T 无关的上下文中执行的,并且 Args 中的任何类型。

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

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

使is_constructible 检查上下文相关是很疯狂的;这意味着同一类型 is_constructible&lt;T, Args...&gt; 在不同的上下文中具有不同的基类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-31
    • 2012-09-19
    相关资源
    最近更新 更多