Template specialisation of static members

H

helfer thomas

Another "template newbie" question. I would like to write the following
code :

-------------
template<typename T, typename U>
struct Test{

static const bool Cond;

};

template<typename T, typename U>
const bool Test<T,U>::Cond = false;

template<typename T>
const bool Test<T,T>::Cond = true;
------------------

As you might expect, it doesn't work, at least under Microsoft Visual
C++ 2005 Express Edition. More precisely, it gives me the following
error at the last line of the code :

error C3860: template argument list following class template name must
list parameters in the order used in template parameter list

Can someboby explain me what I have done wrong ?

Sincerely,

Helfer Thomas
 
A

andy

Can someboby explain me what I have done wrong ?

I think what you want is to specialise the class:

template<typename T, typename U>
struct Test{
static const bool Cond = false;
};

template<typename T>
struct Test<T,T>{
static const bool Cond = true;
} ;

I also provide a suggested alternative which is **unofficially as yet
** becoming the accepted format for doing this type of thing. You will
need the http://www.boost.org libraries to compile where you can read
more about it in docs too:

// alternate using socalled 'metafunction forwarding'
// and mechanism proposed for standardisation
// 'value' member name is common convention too

#include <boost/type_traits/integral_constant.hpp>
template<typename T, typename U>
struct Test1 : boost::integral_constant<bool,false>{};
template<typename T>
struct Test1<T,T> : boost::integral_constant<bool,true>{};


// check it all works
#include <iostream>

int main()
{
std::cout << Test<int,double>::Cond <<'\n';
std::cout << Test<int,int>::Cond <<'\n';

//***standardised*** format
std::cout << Test1<int,double>::value <<'\n';
std::cout << Test1<int,int>::value <<'\n';
}

regards
Andy little
 
V

Victor Bazarov

helfer said:
Another "template newbie" question. I would like to write the
following code :

-------------
template<typename T, typename U>
struct Test{

static const bool Cond;

};

template<typename T, typename U>
const bool Test<T,U>::Cond = false;

template<typename T>
const bool Test<T,T>::Cond = true;

As Andy explained, you cannot specialise a member without specialising
the whole class. However, there is an alternative even to the Boost-
based solution he suggested. Use supplemental template:

template<class T, class U> struct same { enum { yes = 0 }; };
template<class T> struct same<T,T> { enum { yes = 1 }; };

template<typename T, typename U>
struct Test {
static cosnt bool Cond = same<T,U>::yes;
... // if you need more stuff here
};

Don't forget to define the 'Cond' member outside the class if you do
take its address anywhere.

Now, this technique allows you to avoid redefining the entire 'Test'
class just to give 'Cond' static member different values for different
specialisations.

Good luck!

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top