Problem with C++ Partial Template Specialization
I have a situation similar to this:
template<class A, class B>
class MyClass<A, B>
{
...
static A RARELY_USED_A;
}
// Seems to work but does not cover all possible cases, since
// there may be instances of A that have no numeric limits.
template<class A, class B>
A MyClass<A, B>::RARELY_USED_A= std::numeric_limits<A>::max();
From what I saw this seems to work. However, strings may be used as A under some circumstances and so I thought I'd simply create a specialization for this special case.
// Does not complile
template<class B>
string MyClass<string, B>::RARELY_USED_A= "";
unfortunately this does not complie properly with error msg:
error: template definition of non-template 'std::string MyClass<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, B>::RARELY_USED_A'
Note that, on the othre hand, a full specialization seems to work (untested at runtime but compiles)
// This complies but is not gernic enough and hence useless to me
template<>
string MyClass<string, string>::RARELY_USED_A= "";
I assume, I must be doing something wrong. I would be really grateful if you could point out what exactly it is. I thought partical sp开发者_Go百科ecializations were supposed to work this way.
Thanks a lot in advance.
e: edited the name of the DEFAULT_A to RARELY_USED_A, because I thought that "default" was misleading somehow
Use inheritance to reuse and specialize without duplicating all the common code:
template<typename A>
struct RarelyUsedShared
{
static A RARELY_USED_A;
};
template<typename A>
A RarelyUsedShared<A>::RARELY_USED_A = std::numeric_limits<A>::max();
template<>
string RarelyUsedShared<string>::RARELY_USED_A = "";
template<typename A, typename B>
class MyClass<A, B> : RarelyUsedShared<A>
{
...
};
Note that this will result in sharing the member across various B
, which is ok if the member should be const
. If not, the helper can take two template parameters, and you can partially specialize it:
template<typename A, typename B>
struct RarelyUsedNotShared
{
static A RARELY_USED_A;
};
template<typename A, typename B>
A RarelyUsedNotShared<A, B>::RARELY_USED_A = std::numeric_limits<A>::max();
template<typename B>
struct RarelyUsedNotShared<string, B>
{
static A RARELY_USED_A;
};
typename<typename B>
string RarelyUsedNotShared<string, B>::RARELY_USED_A = "";
template<typename A, typename B>
class MyClass<A, B> : RarelyUsedNotShared<A, B>
{
...
};
You need to give a partial specialization to your entire class, not just a single member.
If your RARELY_USED
is const, you could use a little helper class:
template <class A, class B>
const A MyClass<A, B>::RARELY_USED_A = Helper<A>::value;
/*...*/
#include <limits>
#include <string>
template <typename A> struct Helper { static const A RARELY_USED_A; };
template <typename A> const A Helper<A>::RARELY_USED_A = std::numeric_limits<A>::max();
template <> struct Helper<std::string> { static const std::string RARELY_USED_A; };
const std::string Helper<std::string>::RARELY_USED_A = "";
精彩评论