2011-12-13 101 views
7

虽然我自己的类型擦除迭代器工作时,我遇到了一个问题,即编译器(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, void, char> a; 
    a.a(); 
    a.c(); 
    any<int, char> b; 
    b.a(); 
    b.b(); 
    return 0; 
} 

很显然,我已经删除了所有我能在错误仍然存​​在的地方。 (Origional代码是780+行)删除任何剩余的模板参数会导致代码编译。

完整的错误信息是:

main.cpp(23): fatal error C1063: compiler limit : compiler stack overflow 
    main.cpp(20) : see reference to class template instantiation 'from<basetype,void,valuetype>' being compiled 

IDEOne compiles it fine。我听说MSVC实现了两阶段查找错误,这似乎相关,但并不能解释为什么当我删除使from继承base的行时。 任何人都可以教我为什么MSVC10不会编译这个?我该做什么,我应该避免?

+0

对于什么是值得的,GCC 4.6编译示例代码无故障(在Linux/Debian的/ SID/AMD64)。也许你可以切换到GCC(例如一些MinGW或Cygwin变种......)? – 2011-12-13 20:58:20

+0

我实际上通过IDEOne做了大量的调试,但是我的命令行fu和linux很弱,所以Cygwin很害怕。尽管如此,我开始玩弄它。 – 2011-12-13 21:01:08

+0

你有一个模板类继承自己?或者我看到这个错误? – AJG85 2011-12-13 21:17:07

回答

1

作为解决办法,考虑非特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 category, 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,void,valuetype> 
     : public base //commenting out _either_ of these makes it compile 
     , public any<void,valuetype> 
{}; //this is line 23, where the compiler crashes 

int main() {return 0;} 
1

好吧,我放弃了,但我还是设法发出警示:

template <typename T1, typename T2> 
class Any; // forward 

template <typename T2> 
class Any<void, T2> // partial spec of forward 
{}; 

template <typename T1, typename T2> 
class Any: // template definition 
    public Any<void, T2> // inherit from partial spec 
{}; 

template <typename T1, typename T2> 
class From : 
    public Any<int, T2>, // inherit definition 
    public Any<void, T2> // inherit definition or partial spec? 
    // with spec first we get fatal error C1063: compiler limit : compiler stack overflow (CRASH!) 
    // with definition first we get warning C4584: 'From<T1,T2>' : base-class 'Any<void,T2>' is already a base-class of 'Any<int,T2>' 
{}; 

int main() 
{ 
    return 0; 
} 
1

简单的解决方法:更换:

template<class category, class valuetype> 
class any : public any<void, valuetype> 
{ 
}; 

有:

template<class valuetype, class category> 
class any : public any<void, valuetype> 
{ 
};