While working on my own type erasure iterator, I ran into an issue where the compiler (MSVC10) crashed with a stack overflow on this code:
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;
}
Obviously, I've removed everything I can where the bug remains. (Origional code was 780+ lines) Removing any remaining template parameters causes the code to compile.
The full error message is:
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. I've heard that MSVC implemented two-phase lookup wrong, which seems relevant, but doesn't explain why it compiles when I remove the line that makes from
inherit from base
. Can anyone teach me why MSVC10 won't compile this? What did I do that I should be avoiding?
iterator_from_any<category>
inherits from theiterator_from_any<void>
specialization, which is legal C++, but might be what's tripping up MSVC10. – Boneany
is a nested abstract interface, andfrom
is a nested implementation. – Bone