Start New Discussion within our Software Development Community

Hello,

I implemented the follolwing function:

template< int n >
struct GetNRands{
	static void fillVector( set<int>& v, int max ){	
		if( n > 0 ){
			int f;
			int pos;

			do{
				f = rand();
				pos = f * max / RAND_MAX;
			}
			while( v.find( f ) != v.end());

			v.insert( pos );
			GetNRands< n - 1 >::fillVector( v, max );
		}
		return;
	}
};

... but the compiler gets stuck and doesn't finish the build (VC++ compiler).
This can be easily solved by removing the if condition and specializing the template for the case n = 0:

template< int n >
struct GetNRands{
	static void fillVector( set<int>& v, int max ){	
		//if( n > 0 ){
			int f;
			int pos;

			do{
				f = rand();
				pos = f * max / RAND_MAX;
			}
			while( v.find( f ) != v.end());

			v.insert( pos );
			GetNRands< n - 1 >::fillVector( v, max );
		//}
		return;
	}
};

template<>
struct GetNRands<0>{
	static void fillVector( set<int>& v, int max ){}
};

Can someone explain to me why doesn't the first version compile?

Greetings,
Rui

The template generation does not pay attention to executable statements in the template definition. The if (n > 0) does not prevent recursive template bootstapping for GetNRands<0>, GetNRands<-1> and so on. It's pity that VC++ can't detect this "instantiate forever" recursion.

To break this recursion you may define this template specialization for n = 0:

template <> 
struct GetNRands<0> {
static void fillVector( set<int>& v, int max ){}
};

It's a template generation analogue of sacramental if (n == 0) return 1; in famous (and the same absurd) recursive factorial ;)

Comments
Absolutely! O_O
This question has already been answered. Start a new discussion instead.