c++ - 重新定义专业化的真正原因是什么
问题描述
例如
template<typename T,typename U>
struct Test{
}
int main(){
Test<int,void> b;
}
template<>
struct Test<int,void>{
}
这段代码会导致编译错误,错误说“显式特化;‘特化’已经被定义”,我们知道不允许重复显式特化,所以我猜编译器是否生成相同的代码
template<>
struct Test<int,void>{
}
在 POI,以及我在 main 函数之后定义的相同代码,这是重新定义显式特化的原因吗?
解决方案
为了使问题更加明显:让我们的基本模板和专业化有所不同:
template<typename T, typename U>
struct Test
{
T t;
U u;
void someFunction() { }
};
template<typename T>
struct Test<T, void> // partial specialisation this time - yes, possible, too...
{
std::vector<T> t;
double someTotallyDifferentFunction(std::string const&) const { }
};
现在,任何第二个模板参数为 void 的实例化都将具有一个向量,任何其他实例化都将具有这两个成员。
但是,如果您现在在定义专业化之前实例化基本模板,您会遇到麻烦:
template<typename T, typename U>
struct Test { /* as above */ };
Test<int, void> global_t;
template<typename T>
struct Test<T, void> { /* as above */ };
在global_t
声明时,仅存在基本模板。所以它将被实例化(在特定情况下,这实际上将无法编译,因为你不能声明u
类型的成员变量(!)void
,但这是另一个问题,让我们暂时忽略它)。
在实例化之前,编译器需要Test<int, void>
隐式专门化(因此已经存在一种专门化)。但随后编译器发现了显式特化——这与之前的隐式特化相冲突。
结论:您需要在实例化之前进行专业化......