为何Visual C++无法对模板内的类进行偏特化?附代码报错示例
为什么Visual C++ 2015处理不了这个嵌套模板偏特化?
哎,这个问题我之前帮朋友排查过,本质是VC2015对C++模板偏特化的语法支持有个老缺陷,咱们先把问题摆清楚:
你的问题代码
template<int V> struct outer { template<int U, bool> struct inner; }; template<int V> template<bool B> struct outer<V>::inner<V, B> { enum { value = 0 }; }; int main() { return outer<1>::inner<1, false>::value; }
触发的编译错误
Temp.cpp(13): error C2027: 使用未定义的类型'outer<1>::inner<1,false>'
Temp.cpp(13): note: 请参见'outer<1>::inner<1,false>'的声明
问题根源
按照C++标准,你的代码写法是完全合法的:你想要偏特化outer<V>::inner<U,B>,把内部模板的第一个参数U绑定到外部模板的参数V上。但VC2015的模板解析器没实现好这个规则——它没法识别“用外部模板参数作为内部模板偏特化参数”的场景,会错误地认为你写的偏特化和主模板不匹配,所以在实例化outer<1>::inner<1,false>时,找不到对应的定义,就报了“未定义类型”的错误。
解决办法
有几个实用的处理方案:
调整内部模板的参数顺序
把不需要绑定的参数(比如那个bool)放在前面,这样VC2015能正确识别偏特化的匹配关系:template<int V> struct outer { template<bool, int U> struct inner; }; template<int V> template<bool B> struct outer<V>::inner<B, V> { enum { value = 0 }; }; int main() { return outer<1>::inner<false, 1>::value; }在类内部直接定义偏特化
把内部模板的主模板和偏特化都放在outer的定义里,这样VC的解析器能更清晰地关联模板参数:template<int V> struct outer { // 先声明主模板 template<int U, bool B> struct inner { }; // 直接在内部定义偏特化 template<bool B> struct inner<V, B> { enum { value = 0 }; }; }; int main() { return outer<1>::inner<1, false>::value; }升级编译器
这个缺陷在Visual Studio 2017及之后的版本里已经被修复了,如果项目允许升级,直接更到新编译器就能彻底解决问题。
内容的提问来源于stack exchange,提问作者user541686
相关产品推荐
相关产品推荐

