我的is_complete类型特征的实现是否暴露了编译器错误?

Mir*_*pas 26 c++ gcc templates clang c++11

我编写了这个C++ 11特征模板来检查类型是否完整:

template <typename...>
using void_t = void;

template <typename T, typename = void>
struct is_complete : std::false_type
{};

template <typename T>
struct is_complete<T, void_t<decltype(sizeof(T))>> : std::true_type
{};
Run Code Online (Sandbox Code Playgroud)

并测试它像这样:

struct Complete {};

int main()
{
    std::cout << is_complete<Complete>::value
              << is_complete<class Incomplete>::value
              << '\n';
}
Run Code Online (Sandbox Code Playgroud)

我希望打印测试程序10,这是我用clang 3.4编译它时得到的输出.但是,当使用gcc 4.9编译时,它会打印11- 错误地识别class Incomplete为完整.

我不确定我的代码是否正确,但在我看来,即使它是错误的,它在两个编译器上也应该表现相同.

问题1:我的代码是否正确?
问题2:我是否在其中一个编译器中发现了错误?

编辑:

我不是要求替换我的代码.我问的是gcc或clang中是否存在错误,以及这个特定结构是否正确.

T.C*_*.C. 28

问题似乎与定义有关void_t.将其定义为

template<typename... Ts>
struct make_void { typedef void type;};

template<typename... Ts>
using void_t = typename make_void<Ts...>::type;
Run Code Online (Sandbox Code Playgroud)

而是10在两个编译器(Demo)上产生正确的result().

我认为这与N3911第2.3 ,论文提议void_tCWG问题1558中提到的问题相同.从本质上讲,该标准尚不清楚别名模板特化中的未使用参数是否会导致替换失败或被忽略.委员会2014年11月会议通过的CWG问题的解决方案澄清void_t了问题中较短的定义应该起作用,GCC 5.0实施了该决议.