Hy,我正在制作一些元编程库,它可以帮助从简单的ad-mixture类到继承构建复杂的对象。
例如,我得到了一些产生一组模板类的机制,每个模板类代表一个属性。
我来到了最终的构建过程,看起来像这样:
class Car : public Position< Size< Color< BaseObj<Car> > > > {/*...*/};
我完全不喜欢它 (BaseObj始终是序列中最内层的模板)
我尝试制作一些处理模板,以便能够像这样编写:
class Car : public Proc< Position, Size, Color, Car > {/*...*/};
但没有成功。
是否可以制作这样的模板?
是否有任何其他更易读的语义可以与一系列这样的嵌套模板具有相同的效果?
答案 0 :(得分:5)
所以,你想......
nest<A, B, C, D>::type<E>
......成为......
A<B<C<D<E>>>>
这是递归的工作。
template <template <typename> typename...>
struct nest;
template <template <typename> typename First,
template <typename> typename... Rest>
struct nest<First, Rest...>
{
template <typename Leaf>
using type = First<typename nest<Rest...>::template type<Leaf>>;
};
template <template <typename> typename Last>
struct nest<Last>
{
template <typename Leaf>
using type = Last<Leaf>;
};
用法示例:
template <typename> struct A { };
template <typename> struct B { };
template <typename> struct C { };
template <typename> struct D { };
struct E { };
int main()
{
static_assert(std::is_same_v<
typename nest<A, B, C, D>::template type<E>,
A<B<C<D<E>>>>
>);
}
答案 1 :(得分:-2)
编辑似乎我误解了这个问题。我以为你想改变你的设计只是简单地使用一个特征列表,而不是递归地嵌套特征。我现在明白你只是在找一个允许你写一个列表的替代品,这个列表可以归结为你的旧设计。但这就留下了一个问题:为什么你真的想坚持这种设计?它有什么用途?我假设它是唯一的原因,那就是你之前无法使用可变参数模板。
我认为我的答案仍然可行,但它需要更改您当前的位置,大小,颜色等的实现。我不能真正建议如何直到您提供更清楚的描述这些事情。< / p>
旧答案:
嗯,如果你把CRTP - 参数放在前面会更容易。
template<class S, class... P>
class Proc : public P...
{
// ...
};
class Car : public Proc<Car, Position, Size, Color> {/*...*/};