首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >广义Mixins

广义Mixins
EN

Stack Overflow用户
提问于 2012-02-19 17:07:50
回答 4查看 620关注 0票数 3

我正在写一些代码,其中我有一个类,可以接受混合作为可变模板参数。但是,我还需要能够通过CRTP惯用法访问基类的mixins。这是一个最小的例子,它不能完全完成我想要的:

代码语言:javascript
复制
template <template <class> class... Mixins>
class Foo : Mixins<Foo<Mixins...>>... {};

但是,我可能传递给Foo的mixin通常会有几个模板参数,如下所示:

代码语言:javascript
复制
template <class Derived, class Type1, class Type2>
class Bar
{
    Derived& operator()()
    {
        return static_cast<Derived&>(*this);
    }
};

如何更改Foo,使其可以从许多基类继承,在这些基类中,我控制每个基类接受的模板参数?如果我给Foo一个模板模板参数列表,以及一个要传递给它们的参数列表,那么我看不出如何能够将每个模板模板参数与它的参数关联起来。到目前为止,我想到了这样的东西,但我不知道该如何进行。

代码语言:javascript
复制
template <template <class...> class T,
    template <class...> class... Ts>
class Foo : /* How do I retrieve the arguments? */
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-02-19 19:01:27

我不太确定我是否理解了这个问题,所以请允许我重新表述它,以便我们可以从正确的角度开始。

在典型的CRTP用例中,您需要将派生类型线程化到基类,同时将其他模板参数传递给各种基类。

也就是说,一个典型的基类是:

代码语言:javascript
复制
template <typename Derived, typename X, typename Y>
struct SomeBase {
};

您需要创建您的类型,以便可以控制XY,同时传递完整的Derived类。

我想我会使用apply技巧从Derived类的参数列表中提供的适配器动态生成基类。

代码语言:javascript
复制
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;
};

然后,您可以将该类型创建为:

代码语言:javascript
复制
typedef MyFoo< SomeBaseFactory<int, float> > SuperFoo;

其中,Foo定义为:

代码语言:javascript
复制
template <typename... Args>
struct Foo: apply<Args, Foo<Args...>>::type... {
};

因为我已经有一段时间没有深入研究模板了,I checked it worked

当然,Factory本身并不是特定于给定类型的,所以我们可以重用您试验过的包装器方法:

代码语言:javascript
复制
template <template <typename...> class M, typename... Args>
struct Factory {
  template <typename Derived>
  struct apply { typedef M<Derived, Args...> type; };
};

是的,it works too

票数 4
EN

Stack Overflow用户

发布于 2012-02-19 17:31:44

如果我没理解错的话,您应该创建模板别名,将每个混入减少为一个模板参数。

代码语言:javascript
复制
template <typename Derived>
using BarIntFloat = Bar<Derived, Int, Float>;

template <typename Derived>
using BazQux = Baz<Derived, Qux>;

typedef Foo<BarIntFloat, BazQux> MyFoo;
票数 2
EN

Stack Overflow用户

发布于 2012-02-19 17:36:49

这是我想出的一个解决方案。也许有一种更优雅的方法可以做到这一点,但我想不出任何方法。需要注意的是,所有使用的mixins都需要首先嵌套在wrapper结构中,以及它们各自的参数。

代码语言:javascript
复制
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;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9347982

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档