I have some template code which compiles fine in VC9 (Microsoft Visual C++ 2008) but won’t compile in GCC 4.2 (on Mac). I’m wondering if there’s some syntactical magic that I’m missing.
Below I have a stripped-down example which demonstrates my error. Sorry if this example seems meaningless, I removed as much as I could to isolate this error.
In particular I have a template class S which has an inner class R which is also a template class. From a top-level template function foo, I am trying to call R::append which is a static member function of R:
template< typename C >
struct S {
template< typename T >
S<C> & append( const T & ) { return *this; }
template< int B >
struct R {
template< typename N >
static S<C> & append( S<C> & s, const N ) {
return s.append( 42 );
}
};
};
template< typename C >
S<C> & foo( S<C> & s, const int n ) {
S<C>::R<16>::append( s, n ); // error: '::append' has not been declared
return s;
}
Anyone out there know what I’m doing wrong?
Having use both Visual Studio and gcc, it’s a known issue 🙂 And I used VS2003 and gcc 3.4.2 so it’s been like that for a while.
If I remember correctly, the problem is due to the way templates are parsed on these compilers.
gcc behaves as stated by the standard, and performs 2 parses:
typenameandtemplatemagic to help understand what’s going onon the other hand, VS only does one parse, at instantiation, and therefore can fully resolve the symbols without
typenameandtemplatehere and there.You have the same thing for methods:
On the same topic, if you do something like:
You need to actually define this
staticattribute for each instantiation of the template, or you’ll have an undefined symbol.VS accepts this syntax:
But gcc asks for a little keyword:
You may think of VS as better since it asks less of you, but on the other hand gcc may warn you of mistakes in your template methods / classes as soon as it parses them the first time (ie without any actual instantiation) and personally, the sooner the better.
Obviously, the good news is that if compiles on gcc (for these issues), it will also compile fine on Visual Studio.
Since I am not a standardista though, I am not sure whether or not the standard actually demands or advises the 2-parses scheme.