有趣的是,GCC 在这个例子中甚至是自相矛盾的。
让我们声明一个不完整的模板类,它应该给出一些我们可以滥用的很好的编译器消息:
template <typename T>
struct type_check;
我们还将制作另一个const char*可用于测试的:
constexpr char NOT_FOO[]{"NOT_FOO"};
现在我们将看到编译器阻塞的内容:
template <const char *NAME> void foo()
{
    type_check<decltype(Value<FOO>)> a;
    type_check<decltype(Value<NAME>)> b;
    type_check<decltype(Value<NOT_FOO>)> c;
    type_check<decltype(Value<FOO>.foo())> d;
    type_check<decltype(Value<NAME>.foo())> e;
    type_check<decltype(Value<NOT_FOO>.foo())> f;
}
以下是 GCC 5.1.0 产生的错误(为清楚起见,稍作编辑):
test.cpp:21:38: error: ‘type_check<Foo> a’ has incomplete type
     type_check<decltype(Value<FOO>)> a;
                                      ^
test.cpp:22:39: error: ‘type_check<Foo> b’ has incomplete type
     type_check<decltype(Value<NAME>)> b;
test.cpp:25:42: error: ‘type_check<char [8]> c’ has incomplete type
     type_check<decltype(Value<NOT_FOO>)> c;
                                       ^
test.cpp:23:44: error: ‘type_check<void> c’ has incomplete type
     type_check<decltype(Value<FOO>.foo())> c;
test.cpp:24:37: error: request for member ‘foo’ in ‘Value<NAME>’, which is of non-class type ‘char [8]’
     type_check<decltype(Value<NAME>.foo())> d;
test.cpp:28:40: error: request for member ‘foo’ in ‘Value<((const char*)(& NOT_FOO))>’, which is of non-class type ‘char [8]’
     type_check<decltype(Value<NOT_FOO>.foo())> f;
让我们一次拿这些。
错误一:
test.cpp:21:38: error: ‘type_check<Foo> a’ has incomplete type
     type_check<decltype(Value<FOO>)> a;
在第一个错误中,我们可以看到 GCC 正确推断出的类型Value<FOO>是Foo。这是我们所期望的。
错误2:
test.cpp:22:39: error: ‘type_check<Foo> b’ has incomplete type
     type_check<decltype(Value<NAME>)> b;
在这里,GCC 正确地进行了转发并得出Value<NAME>了Foo.
错误 3:
test.cpp:25:42: error: ‘type_check<char [8]> c’ has incomplete type
     type_check<decltype(Value<NOT_FOO>)> c;
太好了,Value<NOT_FOO>是"UNKNOWN",所以这是正确的。
错误 4:
test.cpp:23:44: error: ‘type_check<void> c’ has incomplete type
     type_check<decltype(Value<FOO>.foo())> c;
这很好,Value<FOO>是Foo,我们可以调用foo它,返回void。
错误 5:
test.cpp:24:37: error: request for member ‘foo’ in ‘Value<NAME>’, which is of non-class type ‘char [8]’
     type_check<decltype(Value<NAME>.foo())> d;
这是奇怪的。尽管在错误 2 中我们可以看到 GCC 知道 的类型Value<NAME>是Foo,但当它尝试查找foo函数时,它会出错并改用主模板。这可能是函数查找中的一些错误,它不能正确解析非类型模板参数的值。
错误6:
test.cpp:28:40: error: request for member ‘foo’ in ‘Value<((const char*)(& NOT_FOO))>’, which is of non-class type ‘char [8]’
     type_check<decltype(Value<NOT_FOO>.foo())> f;
在这里,我们可以看到编译器在确定主模板时正确选择了主模板Value<NOT_FOO>。我感兴趣的是(const char*)(& NOT_FOO))GCC 推断为NOT_FOO. 也许这是一个指向问题的指针?我不知道。
我建议提交一个错误并指出差异。也许这不能完全回答你的问题,但我希望它有所帮助。