在处理我自己的类型擦除迭代器时,我遇到了一个问题,编译器(MSVC10)在此代码上发生了堆栈溢出崩溃:
struct base {}; //In actual code,this is a template struct that holds data template<class category,class valuetype> struct any; //In actual code,this is abstract base struct template<class basetype,class category,class valuetype> struct from; //In actual code,this is function definitions of any template<class valuetype> struct any<void,valuetype> { void a() {} }; template<class category,class valuetype> struct any : public any<void,valuetype> //commenting this line makes it compile { void b() {} }; template<class basetype,class valuetype> struct from<basetype,void,valuetype> : public base //commenting out _either_ of these makes it compile,public any<void,valuetype> { void c() {} }; int main() { from<int,char> a; a.a(); a.c(); any<int,char> b; b.a(); b.b(); return 0; }
显然,我已经删除了我可以在哪里留下bug. (原始代码为780行)删除任何剩余的模板参数会导致代码编译.
完整的错误消息是:
main.cpp(23): fatal error C1063: compiler limit : compiler stack overflow main.cpp(20) : see reference to class template instantiation 'from<basetype,valuetype>' being compiled
IDEOne compiles it fine.我听说MSVC实现了错误的两阶段查找,这似乎是相关的,但是没有解释为什么当我从base继承而删除行时编译.任何人都可以教我为什么MSVC10不会编译这个?我应该避免做什么?
解决方法
作为一种解决方法,考虑在非专业化的any和category = void的专业化之间引入一个额外的类:
template <class valuetype> class detail_void_any : public any<void,valuetype> { }; template<class category,class valuetype> class any : public detail_void_any<valuetype> { };
以下完整程序应该编译而不会出错:
class base {}; // Data Holder (in reality it's templated,so required) template<class category,class valuetype> class any; // Virtual Function Interface template<class basetype,class valuetype> class from; // Virtual Function Implementation template<class valuetype> class any<void,valuetype> {}; template <class valuetype> class detail_void_any : public any<void,valuetype> { }; template<class category,class valuetype> class any : public detail_void_any<valuetype> { }; template<class basetype,class valuetype> class from<basetype,valuetype> : public base //commenting out _either_ of these makes it compile,valuetype> {}; //this is line 23,where the compiler crashes int main() {return 0;}