Получение специализации класса шаблона на основе работы базовой политики для всех производных политик - PullRequest
3 голосов
/ 11 марта 2012

У меня есть политики, основанные на базовой политике.Некоторые классы специализируются на производных политиках, в то время как другие специализируются только на базовой политике и могут работать со всеми производными политиками.

Проблема, с которой я сталкиваюсь, заключается в слишком большом дублировании кода (в основном конструкторы и некоторый код для самого класса).Приведенный ниже код может дать лучшее объяснение того, что я имею в виду:

struct BasePolicy {};
struct DerivedPolicy1 : public BasePolicy {};
struct DerivedPolicy2 : public BasePolicy {};
//... more policies deriving from BasePolicy (or other BasePolicies)
struct AnotherPolicy {};

template <typename T>
struct Foo;

// This struct can work for all BasePolicy types which includes all derivations
// of it (but doesn't because it is specialized for BasePolicy only)
template<>
struct Foo<BasePolicy>
{
  //... many constructors along with code
};

template<>
struct Foo<AnotherPolicy>
{
  //... more code
};

/* Would like to avoid the following code as it duplicates the above when it 
   comes to constructors and other things such as typedefs */
//template<>
//struct Foo<DerivedPolicy1> : Foo<BasePolicy>
//{
//  //... same constructors as Foo<BasePolicy>
//};
//
//template<>
//struct Foo<DerivedPolicy2> : Foo<BasePolicy>
//{
//  //... same constructors as Foo<BasePolicy>
//};

int main()
{
  // would like this to compile without uncommenting the commented out code and
  // without having the client (i.e. the line below) to somehow get the base
  // type of the policy (although if it can be done transparently, that will
  // work)
  Foo<DerivedPolicy1> a; 
};

Есть ли какой-нибудь способ для принятия производной политики классом, специализированным для базовой политики?Я бы хотел, чтобы клиент не делал ничего лишнего.

Следующее не является допустимым кодом C ++, но я бы хотел, чтобы что-то подобное произошло (если вы помните приведенный выше код):

template<>
struct Foo<BasePolicy | DerivedPolicy1 | DerivedPolicy2>
{
  //... many constructors along with code
};

1 Ответ

5 голосов
/ 11 марта 2012

Это случай для СФИНА.

template< typename Policy, ...some_condition... >
struct Foo<Policy>
{
 ...
};

Вы должны решить, что такое some_condition. Вы можете указать, что Политика является производной от BasePolicy:

template< typename Policy, enable_if< is_base<BasePolicy, Policy> > >

Или вы можете явно указать список разрешенных политик:

template< typename Policy,
           enable_if_c <is_same<Policy, BasePolicy>::value || 
                         is_same<Policy, DerivedPolicy1>::value> || 
                         ...whatever...
                        >
         >
...