【问题标题】:Mixins, variadic templates, and CRTP in C++C++ 中的 Mixin、可变参数模板和 CRTP
【发布时间】:2010-03-17 05:01:27
【问题描述】:

以下是场景:我想要一个宿主类,它可以有可变数量的 mixin(对于可变参数模板不太难——例如,参见 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.103.144)。但是,我还希望 mixins 由宿主类参数化,以便它们可以引用其公共类型(使用 CRTP 习惯用法)。 尝试混合两者时会出现问题——我不清楚正确的语法。 比如下面的代码用g++ 4.4.1编译失败:

template <template<class> class... Mixins>
class Host : public Mixins<Host<Mixins>>... {
  public:
    template <class... Args>
    Host(Args&&... args) : Mixins<Host>(std::forward<Args>(args))... {}
};

template <class Host> struct Mix1 {};

template <class Host> struct Mix2 {};

typedef Host<Mix1, Mix2> TopHost;
TopHost *th = new TopHost(Mix1<TopHost>(), Mix2<TopHost>());

出现错误:

tst.cpp: In constructor ‘Host<Mixins>::Host(Args&& ...) [with Args = Mix1<Host<Mix1, Mix2> >, Mix2<Host<Mix1, Mix2> >, Mixins = Mix1, Mix2]’:

tst.cpp:33:   instantiated from here

tst.cpp:18: error: type ‘Mix1<Host<Mix1, Mix2> >’ is not a direct base of ‘Host<Mix1, Mix2>’

tst.cpp:18: error: type ‘Mix2<Host<Mix1, Mix2> >’ is not a direct base of ‘Host<Mix1, Mix2>’

有没有人成功地将可变参数模板与 CRTP 混合使用?

【问题讨论】:

    标签: g++ c++11 mixins variadic crtp


    【解决方案1】:

    以下似乎有效。我在继承的 mixin 类中添加了Mixins...,它就地扩展了参数包。在Host 模板的主体之外,必须指定Host 的所有模板参数,以便Mixins... 达到目的。在正文中,只需Host 就足够了,无需拼出所有模板参数。有点短手。

    #include <utility>
    
    template <template<class> class... Mixins>
    class Host : public Mixins<Host<Mixins...>>...
    {
      public:
        Host(Mixins<Host>&&... args) : Mixins<Host>(std::forward<Mixins<Host>>(args))... {}
    };
    
    template <class Host> struct Mix1 {};
    template <class Host> struct Mix2 {};
    
    int main (void)
    {
      typedef Host<Mix1, Mix2> TopHost;
      delete new TopHost(Mix1<TopHost>(), Mix2<TopHost>());
    }
    

    【讨论】:

    • 我对其进行了修改以包含模板化构造函数。模板 Host(Args&&... args) : Mixins(std::forward>(args))... {}
    • 谢谢,苏曼特。你的建议是有道理的,但对我来说不起作用。您使用的是哪个编译器版本?我复制并粘贴了这段代码,编译时得到:tst2.cpp: In function 'int main()': tst2.cpp:16: error: no matching function for call to 'Host ::Host(Mix1 >, Mix2 >)' tst2.cpp:7: 注意:候选者是:Host::Host(Mixins >&& ...) [with Mixins = Mix1, Mix2] tst2.cpp:5: 注意:Host::Host(const Host&)
    • 哦,我错过了你的修订。这修复了“无匹配函数”错误,但会因“内部编译器错误”而爆炸 :) 再说一遍,您使用的是哪个编译器?
    • 它只在 g++ 4.5 上对我有用。我从源代码编译它。它在 g++ 4.4.3 上对我不起作用。我遇到了你提到的同样的错误。
    • 如何让传入的 mixin 也可以访问 Host 成员,而不仅仅是类型?我假设唯一的方法是让 mixins 持有对 Host 类的指针/引用。如果我们假设所有 Mixins 都有相同的构造函数 Mix(Host &amp;),这很容易,但是如果像上面给出的示例一样,每个 mixins 构造函数都可以有自己的一组参数呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多