考虑以下伪代码:
template<class... T>
struct worker : unique<T...>::type...{};
struct x{};
struct y{};
struct z{};
是否可以编写一个模板unique
,使其生成一个仅由 s 中唯一类型组成的参数包T
,以便worker<x,y,x,z>
直接从x
、y
、 、z
、 、 、 、 、 、 、 按顺序派生,给定T
的 s 是非最终类?
考虑以下伪代码:
template<class... T>
struct worker : unique<T...>::type...{};
struct x{};
struct y{};
struct z{};
是否可以编写一个模板unique
,使其生成一个仅由 s 中唯一类型组成的参数包T
,以便worker<x,y,x,z>
直接从x
、y
、 、z
、 、 、 、 、 、 、 按顺序派生,给定T
的 s 是非最终类?
阿法克:不。
问题是这type
是typedef
指令的结果,typedef
不能给包起别名。这实际上很麻烦,而且通常对包的计算需要引入包装类型(例如template <typename...> struct pack {};
),以便能够传递它们。
参数包不能轻易存储,所以我不认为你想要的可以做到。但是,由于您似乎需要此功能才能从一组基中继承,因此您可以使用一些模板元编程来创建一个基类型,该基类型从您的集合中的所有基中线性继承。在此之前,您可以轻松地从参数包中过滤重复项。
下面是使用Boost.MPL实现这种方法:
#include <boost/mpl/fold.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/set.hpp>
#include <boost/mpl/vector.hpp>
namespace mpl = boost::mpl;
template < typename ...Args >
struct inherit_uniquely
{
// filter out duplicates
typedef typename
mpl::fold<
mpl::vector< Args... >,
mpl::set0<>,
mpl::insert< mpl::_1, mpl::_2 >
>::type unique_bases;
// create base type
typedef typename
mpl::inherit_linearly<
unique_bases,
mpl::inherit< mpl::_1, mpl::_2 >
>::type type;
};
template < typename ...Bases >
struct Derived : inherit_uniquely< Bases... >::type
{};
struct X { int x;};
struct Y { int y;};
struct Z { int z;};
int main()
{
Derived< X, Y, Z > d;
d.x = 1;
d.y = 2;
d.z = 3;
X& d_as_x = d;
Y& d_as_y = d;
Z& d_as_z = d;
}