有趣的是,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
. 也许这是一个指向问题的指针?我不知道。
我建议提交一个错误并指出差异。也许这不能完全回答你的问题,但我希望它有所帮助。