模板代码上的编译器堆栈溢出
在处理我自己的类型擦除迭代器时,遇到了编译器(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;
}
很明显,我已经删除了所有可以在bug存在的地方。 (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编译它很好。 我听说MSVC实现两阶段查找错误,这似乎有关,但没有解释为什么它编译的时候我删除,使线from
继承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 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;}
我放弃了,但我确实设法发出警告:
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;
}
最简单的解决方法:替换:
template<class category, class valuetype>
class any : public any<void, valuetype>
{
};
有:
template<class valuetype, class category>
class any : public any<void, valuetype>
{
};
链接地址: http://www.djcxy.com/p/10223.html