我有以下代码:
#include <iostream>
class A;
int main()
{
std::cout << std::is_constructible<A>::value << std::endl;
}
当我使用GCC 8.3时,此代码将编译。但是,当我使用Clang 8.0时,出现编译错误,即不能在类型特征中使用不完整的类型。
哪个是正确的?是否允许我在不完整的类型上使用is_constructible
(期望值为false
),还是不允许?
答案 0 :(得分:26)
行为是不确定的。
[meta.unary.prop]
template <class T, class... Args> struct is_constructible;
T
以及参数包Args
中的所有类型均应为完整类型, (可能具有简历资格)空白或未知范围的数组。
That's a precondition的元功能。您的代码违反的合同。通知您,libc ++很慷慨。
请注意,将前提条件放在此处,否则将其保持未定义状态是有原因的。模板的两个实例化点具有不同含义的程序是ill-formed NDR。唯一明智的做法是需求完整类型。毕竟,无论如何这就是特质最有用的时候。
答案 1 :(得分:18)
您的代码导致未定义的行为。
Cppreference状态:
template< class T, class... Args > struct is_constructible;
T和参数包Args中的所有类型均应为完整类型,(可能是经过cv限定)void或未知范围的数组。 否则,行为是不确定的。
答案 2 :(得分:9)
您的代码具有未定义的行为。根据{{3}} std::is_constructible
的要求
T
以及模板参数包Args
中的所有类型应为完整类型, cvvoid
或数组未知范围。
强调我的