Take a look at this snippet of code. Does it look valid to you? On first glance, it might. But if you run it through your compiler… hmm, wait.. MSVC thinks this is valid code too.
template <typename A> class Foo { public: Foo() { Bar<A> b; b.method(); } }; template <typename A> class Bar { public: void method() {} }; int main( int argc, char** argv ) { Foo<char> f; return 0; }
I’m sure we all know how MSVC is lax when it comes to using
typename. The issue
here, though, is that Foo’s constructor refers to Bar, which hasn’t been
declared. GCC complains with error: ‘Bar’ was not declared in this scope
.
MSVC, however, apparently lets this slide and only parses the code for Foo
when it actually instantiates the template. It seems that GCC actually does
the parsing work up front, and only emits code when the template is
instantiated, whereas MSVC saves the parsing for when the template is actually
instantiated.
So, be warned. If you’re developing (or maintaining…) template-heavy code that’s supposed to be portable with MSVC, compile early and often with GCC.