不完整类型上的std :: is_constructible

时间:2019-04-24 13:42:42

标签: c++ c++11 language-lawyer

我有以下代码:

#include <iostream>

class A;

int main()
{
    std::cout << std::is_constructible<A>::value << std::endl;
}

当我使用GCC 8.3时,此代码将编译。但是,当我使用Clang 8.0时,出现编译错误,即不能在类型特征中使用不完整的类型。

哪个是正确的?是否允许我在不完整的类型上使用is_constructible(期望值为false),还是不允许?

3 个答案:

答案 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中的所有类型应为完整类型 cv void或数组未知范围。

强调我的