首页 > 解决方案 > 重新定义专业化的真正原因是什么

问题描述

例如

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 函数之后定义的相同代码,这是重新定义显式特化的原因吗?

标签: c++

解决方案


为了使问题更加明显:让我们的基本模板和专业化有所不同

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> 隐式专门化(因此已经存在一种专门化)。但随后编译器发现了显式特化——这与之前的隐式特化相冲突。

结论:您需要在实例化之前进行专业化......


推荐阅读