基于基本策略工作的所有派生策略获得模板类专门化

Sam*_*rsa 3 c++ templates code-duplication

我有一些衍生自基本政策的政策。一些类专门针对派生策略,而另一些类仅专门针对基本策略,并且可以与所有派生策略一起使用。

我遇到的问题是太多的代码重复(主要是类本身的构造函数和一些样板代码)。下面的代码可能会更好地解释我的意思:

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; 
};
Run Code Online (Sandbox Code Playgroud)

有什么方法可以使派生策略被基础策略专用的类接受吗?我希望客户不要做任何额外的事情。

以下是无效的C ++代码,但我希望发生这种情况(如果您牢记上面的代码):

template<>
struct Foo<BasePolicy | DerivedPolicy1 | DerivedPolicy2>
{
  //... many constructors along with code
};
Run Code Online (Sandbox Code Playgroud)

n. *_* m. 5

SFINAE就是这种情况。

template< typename Policy, ...some_condition... >
struct Foo<Policy>
{
 ...
};
Run Code Online (Sandbox Code Playgroud)

您应该确切确定什么是some_condition。您可以指定Policy源自BasePolicy:

template< typename Policy, enable_if< is_base<BasePolicy, Policy> > >
Run Code Online (Sandbox Code Playgroud)

或者,您可以明确列出允许的策略:

template< typename Policy,
           enable_if_c <is_same<Policy, BasePolicy>::value || 
                         is_same<Policy, DerivedPolicy1>::value> || 
                         ...whatever...
                        >
         >
Run Code Online (Sandbox Code Playgroud)