作者热门文章
- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有以下代码:
typedef vector<int> Vec;
typedef vector<Vec> VecOfVec;
template<typename Vec>
Vec DoSomething(const Vec &v);
template<>
VecOfVec DoSomething<VecOfVec>(const VecOfVec &v)
{
VecOfVec r;
for(auto i = v.begin(); i != v.end(); i++)
r.push_back(DoSomething(*i));
return r;
}
template<>
Vec DoSomething<Vec>(const Vec &v) // Error here
{
return v; // for the sake of the example
}
我收到以下错误:
explicit specialization of 'DoSomething<vector<int> >' after instantiation
在标记线处。
编译器坚持它已经实例化了 DoSomething<vector<int> >
,虽然它不能,但一个简单的程序可以证明它:
typedef vector<int> Vec;
typedef vector<Vec> VecOfVec;
template<typename Vec>
Vec DoSomething(const Vec &v);
template<>
VecOfVec DoSomething<VecOfVec>(const VecOfVec &v)
{
VecOfVec r;
for(auto i = v.begin(); i != v.end(); i++)
r.push_back(DoSomething(*i));
return r;
}
导致 Unresolved external 问题。
为什么编译器说它已经实例化了它,而它不能甚至没有?为什么编译器不将其视为未解析的符号,而链接器却将其视为未解析的符号?我知道切换方法顺序可以解决它,但我想知道编译器为什么要这样做。
最佳答案
代码在 DoSomething(*i)
请求了一个隐式实例化。 .您没有在该翻译单元中定义模板这一事实意味着它无法实例化特化,因此 DoSomething(*i)
在您的情况下会产生“未解析的符号”(链接器)错误。要消除该错误,您必须在该 TU 中定义模板,或者在定义模板的 TU 中提供该模板的显式实例化指令。
代码请求隐式实例化以进行特化的事实DoSomething<vector<int> >
在您明确提供特化足以使程序不正确之前(尽管不需要诊断;编译器在这里做得很好,但不需要这样做)。
正如@CharlesBailey 有用地指出的那样,声明明确的特化就足够了;它的定义可以在其他地方给出,甚至在使用 TU 之外。
关于c++ - 实例化后的显式特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7774188/
我是一名优秀的程序员,十分优秀!