2011-12-13 92 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> 
{ 
};