我发现了这段虚假代码(下面的设计示例):
template <int I, typename T>
struct foo
{
static int bar()
{
return 1;
}
};
template <std::size_t Index, typename T>
struct foo<Index, T*>
{
static int bar()
{
return 2;
}
};
请注意,专业化使用不同类型(错误)。令人惊讶的是,它在没有GCC 4.8.1和Clang 3.4的任何错误(或警告)的情况下进行编译。但是对于GCC行foo<0, int*>::bar()
来说更奇怪的是1
,但Clang给出了2
。到底是怎么回事?是否仍然被标准视为专业化?
答案 0 :(得分:2)
Gcc错了,因为你根本无法调用这种专业化。 只需删除主要模板定义:
template <int I, typename T>
struct foo;
template <std::size_t Index>
struct foo<Index, int*> {
static int bar() {
return 2;
}
};
int main() {
std::cout << foo<std::size_t(0), int*>::bar() << std::endl; // nope, not work
std::cout << foo<0, int*>::bar() << std::endl; // nope, not work
}
查看直播example。并且this代码必须报告模糊的部分特化,但它不是(对于gcc)。 Clang report“含糊不清”。
PS我认为,这部分标准不够涵盖。
<强>更新强>
在这种情况下,clang不适用于枚举,example。
答案 1 :(得分:0)
对非类型模板参数14.5.5 [temp.class.spec]第8段部分专门化类模板的限制列出了以下限制:
部分专用的非类型参数表达式不应涉及部分特化的模板参数,除非参数表达式是简单标识符。
使用size_t
的参数表达式涉及到int
的转换(size_t
是无符号的),因此不是简单的标识符。