我正在写一些代码,其中我有一个类,可以接受混合作为可变模板参数。但是,我还需要能够通过CRTP惯用法访问基类的mixins。这是一个最小的例子,它不能完全完成我想要的:
template <template <class> class... Mixins>
class Foo : Mixins<Foo<Mixins...>>... {};但是,我可能传递给Foo的mixin通常会有几个模板参数,如下所示:
template <class Derived, class Type1, class Type2>
class Bar
{
Derived& operator()()
{
return static_cast<Derived&>(*this);
}
};如何更改Foo,使其可以从许多基类继承,在这些基类中,我控制每个基类接受的模板参数?如果我给Foo一个模板模板参数列表,以及一个要传递给它们的参数列表,那么我看不出如何能够将每个模板模板参数与它的参数关联起来。到目前为止,我想到了这样的东西,但我不知道该如何进行。
template <template <class...> class T,
template <class...> class... Ts>
class Foo : /* How do I retrieve the arguments? */发布于 2012-02-19 19:01:27
我不太确定我是否理解了这个问题,所以请允许我重新表述它,以便我们可以从正确的角度开始。
在典型的CRTP用例中,您需要将派生类型线程化到基类,同时将其他模板参数传递给各种基类。
也就是说,一个典型的基类是:
template <typename Derived, typename X, typename Y>
struct SomeBase {
};您需要创建您的类型,以便可以控制X和Y,同时传递完整的Derived类。
我想我会使用apply技巧从Derived类的参数列表中提供的适配器动态生成基类。
template <typename Derived, typename X, typename Y>
struct SomeBase {};
template <typename X, typename Y>
struct SomeBaseFactory {
template <typename Derived>
struct apply { typedef SomeBase<Derived, X, Y> type; };
};
// Generic application
template <typename Fac, typename Derived>
struct apply {
typedef typename Fac::template apply<Derived>::type type;
};然后,您可以将该类型创建为:
typedef MyFoo< SomeBaseFactory<int, float> > SuperFoo;其中,Foo定义为:
template <typename... Args>
struct Foo: apply<Args, Foo<Args...>>::type... {
};因为我已经有一段时间没有深入研究模板了,I checked it worked。
当然,Factory本身并不是特定于给定类型的,所以我们可以重用您试验过的包装器方法:
template <template <typename...> class M, typename... Args>
struct Factory {
template <typename Derived>
struct apply { typedef M<Derived, Args...> type; };
};是的,it works too。
发布于 2012-02-19 17:31:44
如果我没理解错的话,您应该创建模板别名,将每个混入减少为一个模板参数。
template <typename Derived>
using BarIntFloat = Bar<Derived, Int, Float>;
template <typename Derived>
using BazQux = Baz<Derived, Qux>;
typedef Foo<BarIntFloat, BazQux> MyFoo;发布于 2012-02-19 17:36:49
这是我想出的一个解决方案。也许有一种更优雅的方法可以做到这一点,但我想不出任何方法。需要注意的是,所有使用的mixins都需要首先嵌套在wrapper结构中,以及它们各自的参数。
template <template <class...> class Mixin, class... Args>
struct wrapper
{
typedef Mixin<Args...> type;
};
template <class... Args>
struct test
{
};
template <class Arg, class... Args>
struct test<Arg, Args...> : Arg::type, test<Args...>
{
};
template <class T>
class mixin1 {};
template <class T1, class T2>
class mixin2 {};
template <class T1, class T2, class T3>
class mixin3 {};
int main()
{
test<wrapper<mixin1, int>, wrapper<mixin2, int, float>> foo;
return 0;
}https://stackoverflow.com/questions/9347982
复制相似问题