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

Define a Specialization As Instantiation of Another Class

本文关键字:实例化 另一个 专业化 定义      更新时间:2023-10-16

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

//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,尽管可以接受更高版本

间接寻址在这里有帮助吗?:)

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;

您可以使用继承而不是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; };