开发者

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 = "";
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜