【发布时间】:2020-03-02 14:08:25
【问题描述】:
std::is_constructible 处理私有构造函数的规则是什么?给定以下代码:
#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 真的那么矛盾?
【问题讨论】:
-
看起来像一个 GCC 错误,clang 9 prints
00 -
在我的机器上使用 c++17 g++9.2.1 / g++-10.0 编译并将 std::is_constructible<...>::value 替换为 is_constructible_v,那是result changes to 00
-
@mutableVoid 确实——而且似乎
::value版本也能够改变之前的输出:godbolt.org/z/zCy5xU 取消注释行并且在 gcc 中全部变为 1:s。 -
另一种修复方法:godbolt.org/z/EKaP3r 所以基本上这是某种评估顺序错误。
-
@mutableVoid 你甚至不需要实例化函数模板来实现它。在这个例子中,它返回
false,但是如果函数模板被取消注释,它突然返回true:godbolt.org/z/zqxdk2
标签: c++ typetraits