c++ - std::is_constructible 为私有(private)构造函数返回不一致的值

标签 c++ typetraits

std::is_constructible 的规则是什么?处理私有(private)构造函数?给定以下代码:

#include <iostream>

class Class {
private:
    Class() { }
};

template <typename T>
class Test {
public:
    static void test() {
        std::cout
            //<< std::is_constructible<Class>::value
            << std::is_constructible<T>::value
            << std::endl;
    }
};

int main() {
    Test<Class>::test();
}

这将打印 0 ( ideone ),即 T不是默认可构造的。

取消注释注释行,它会打印 11 ( ideone ),所以 T突然变成了默认可构造。

我可以找到支持这两个结果的理由,但我不明白包含注释行如何改变第二个结果。这是以某种方式调用UB吗?这是编译器错误吗?或者是 std::is_constructible真的那么矛盾吗?

最佳答案

std::is_constructible应该返回 false在这种情况下,因为构造函数不可访问。

正如问题下方所指出的,问题中描述的行为是由 GCC/libstdc++ 中的错误引起的。错误是 reported here ,并且,根据 Bugzilla,如果不是由 access control bug for classes in template functions 引起,则与这已经很久没有解决了。这两个 bug 之间的关系取自 Jonathan Wakely 的 Bugzilla 评论,他似乎首先检测到了这两个 bug 之间的联系。

当删除构造函数而不是将其设为私有(private)时,GCC 中此场景的行为变得正确,这也暗示了这一点:

class Class {
    Class() = delete;
};

打印出 000分别。
这是正确的输出(clang 在使用私有(private)构造函数的场景中也正确报告)。

这可以解释 observed change of behavior在该行中进行注释时,因为在模板化结构中的函数内部,访问检查不起作用,并报告构造函数在不可访问时是可访问的。当在下一行或可能在完全不同的位置再次检查特征时(如 here 的情况),它已经被实例化,因此会产生错误的答案。

关于c++ - std::is_constructible 为私有(private)构造函数返回不一致的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60490574/

相关文章:

c++ - 如何找到对象由哪些模板层组成?

c++ - 为什么在 C++20 中不推荐使用 std::is_pod?

c++ - "class ClassName;"放在其他类定义的头文件中是什么意思?

c++ - 具有局部静态变量的 ID 生成器 - 线程安全?

c++ - 枚举基类型的模板优化

c++ - standard_layout 类的数据成员是否与对象的地址有固定的偏移量?

c++ - 如何检测字符串文字

c++ - 如何为动态加载编写 MPI 包装器

c++ - 这个结构继承的类型是什么?

c++ - 使用 type_traits 检查常量