将专业化定义为另一个类的实例化

时间:2016-04-29 02:54:31

标签: c++ c++14 specialization

我有一种情况,我想定义一个专门化另一个类的实例化相同。这是我想要的一个简单示例(在此示例中为完整的实例化;在我的实际问题中,我想要部分特化):

//Template class
template <int i> class Foo { /*...*/ };

//Another, completely different, template class
template <int i,int j> class Bar { /*...*/ };

//Ordinary specialization of Foo
template <> class Foo<0> { /*...*/ };

//Bogus specializations of Foo that
//  hopefully explain what I want.
template <> class Foo<1> = Bar<1, 11>;
template <> class Foo<2> = Bar<2, 42>;
template <> class Foo<3> = Bar<3,-71>;
...

这样做有什么好处? Foo<1>Foo<2>等的定义相当复杂,但很容易将其作为模板编写一次。有很多这样的定义。将Bar定义为Foo并不是一个选项。只有一些值可以专门化,Bar的特化必须手动选择(因此int j的随机数)。

我通常会使用CRTP来达到这个效果。我会对Bar做一些相当讨厌的修改,然后执行类似的操作:

template <> class Foo<1> : public Bar<1, 11,Foo<1>> {};
template <> class Foo<2> : public Bar<2, 42,Foo<2>> {};
template <> class Foo<3> : public Bar<3,-71,Foo<3>> {};
...

显然,Bar需要被修改,可能会有一些using声明来拉低构造函数。这会很混乱。

我的问题:我能做得比这更好吗?也就是说,可以将专门化定义为另一个模板类的实例化吗?

注意:首选标准是C ++ 14,尽管后面的版本是可以接受的。

2 个答案:

答案 0 :(得分:1)

间接帮助吗? :)

template<int i> struct Indirection { using type = Foo<i>; };

template <> class Indirection<1> { using type = Bar<1, 11>;  };
template <> class Indirection<2> { using type = Bar<2, 42>;  };
template <> class Indirection<3> { using type = Bar<3, -71>; };

template<int i>
using ActualFoo = typename Indirection<i>::type;

答案 1 :(得分:0)

您可以使用继承而不是CRTP。

template <int i> struct Foo {};

template <int i,int j> struct Bar { Bar() {} };

template <> struct Foo<0> {};

template <> struct Foo<1> : public Bar<1, 11> { using Bar::Bar; };
template <> struct Foo<2> : public Bar<2, 42> { using Bar::Bar; };
template <> struct Foo<3> : public Bar<3,-71> { using Bar::Bar; };