:::: www.foddex.net ::::
      Home      |      Blog      Tutorials      Reviews      |      Resume      Portfolio      |      Photos      Stuff      |      Unreal      Flame      |      Links
Foddex' head
Contact me

Stuff
NL Weather
NL Precipitation
Temperature
xkcd
ICHC
Slashdot
Kitten
wliia
TBBT - Zoom Zoom!!

BLOG: C++ static template members

posted Fri 07-03-2008 16:05:19, in the c++ (c++) category

I'm always looking for new fun ways to abuse...^H^H^H^H^Huse C++. Today I stumbled on a fun difference between MSVC++ and gcc, the problem mainly being that MSVC++ has its own notion of what C++ is, and gcc simply following the appropriate standard(s).

Check out the following code.

template<typename _T>
class A {
	_T foo;
};

template<typename _T>
class B {
	public:
		struct subB {
			static A<float> myA;
			const char* name;
			subB( const char* _name ) : name( _name ) {}
		};
		static typename B<_T>::subB mySubB;
};

Suppose you use class B with type int. Then you need to define the two static members in the class. How to do this? My instinct said I needed to do this:
A<float> B<int>::subB::myA;
B<int>::subB B<int>::mySubB( "int" ); 

And, in fact, MSVC++ eats this eagerly and does exactly what you'd expect. However, using gcc to compile this code I got the following error on both lines: too few template-parameter-lists.

After blinking at the error for 5 minutes, I decided to google for it and found out that - not at all unexpected - you have to do this in a more generic, template-like way:

template<typename _T> A<float> B<_T>::subB::myA;
template<typename _T> typename B<_T>::subB B<_T>::mySubB( "generic" );

Isn't that glorious C++ code? :D You gotta love this kinda stuff. And ofcourse, you can specialize this for specific types. Suppose we want the static variables to be instantiated differently when we use class B with type float. Then we type this:
template<> A<float> B<float>::subB::myA;
template<> B<float>::subB B<float>::mySubB( "float" );

Template specialization, you gotta love it! :D And now for the test:

int main( int, char** ) {
	
	printf( "%s\n", B<int>::mySubB.name );
	printf( "%s\n", B<float>::mySubB.name );
	return 0;
}
Which outputs the following:
generic
float
Exactly as you'd expect.

If you reached here without skipping any text, coolio ;)


-- Foddex

[ Back to blog listing ]

0 comment(s)

Leave a comment

Name (required)
URL
Copy this code2-212-110-748

Pressure building on my soul
I ask God to take control
Guide me through this fucked up world

-

I know someday you'll have a beautiful life, I know you'll be a star
In somebody else's sky, but why, why, why
Can't it be, can't it be mine