Проблема с C ++ частичной специализацией шаблонов - PullRequest
3 голосов
/ 14 июля 2011

У меня есть ситуация, подобная этой:

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();

Из того, что я увидел, это похоже на работу. Тем не менее, строки могут использоваться как A при некоторых обстоятельствах, и поэтому я подумал, что просто создам специализацию для этого особого случая.

// Does not complile
template<class B>
string MyClass<string, B>::RARELY_USED_A= "";

к сожалению, это не соответствует должным образом с сообщением об ошибке:

error: template definition of non-template 'std::string MyClass<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, B>::RARELY_USED_A'

Обратите внимание, что, с другой стороны, полная специализация, кажется, работает (не проверена во время выполнения, но компилируется)

// This complies but is not gernic enough and hence useless to me
template<>
string MyClass<string, string>::RARELY_USED_A= "";

Полагаю, я что-то не так делаю. Я был бы очень признателен, если бы вы могли указать, что именно. Я думал, что частичные специализации должны были работать таким образом.

Заранее большое спасибо.

e: изменил имя DEFAULT_A на RARELY_USED_A, потому что я думал, что «default» каким-то образом вводит в заблуждение

Ответы [ 3 ]

4 голосов
/ 14 июля 2011

Используйте наследование для повторного использования и специализации без дублирования всего общего кода:

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>
{
  ...
};

Обратите внимание, что это приведет к разделению члена между различными B, что нормально, если член должен быть const.Если нет, помощник может принимать два параметра шаблона, и вы можете частично специализировать его:

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>
{
  ...
};
1 голос
/ 14 июля 2011

Вам нужно дать частичную специализацию всему классу, а не только одному члену.

0 голосов
/ 14 июля 2011

Если ваш RARELY_USED является константой, вы можете использовать маленький вспомогательный класс:

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 = "";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...