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的说法,该错误与不是由一段时间 Unresolved access control bug for classes in template functions引起的有关。这两个错误之间的关系来自乔纳森·韦克利(Jonathan Wakely)的Bugzilla评论,该评论似乎首先检测到这两个错误之间的联系。
这也暗示了以下事实:删除构造函数而不是将其私有(private)化后,GCC中此方案的行为变得正确:
class Class {
Class() = delete;
};
分别打印出
0
和00
。这是正确的输出(在带有私有(private)构造函数的情况下,
clang
也会正确报告该输出)。在行中注释时,这可以解释observed change of behavior,因为在模板化结构的函数内部,访问检查不起作用,并且报告了构造函数不可访问的情况。当在下一行或可能在完全不同的位置再次检查特征时(如here情况),该特征已被实例化,因此产生错误的答案。
关于c++ - std::is_constructible为私有(private)构造函数返回不一致的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60490574/