简体   繁体   English

使用可变参数模板解决C ++中的mixin构造函数问题

[英]Solving the mixin constructor problem in C++ using variadic templates

I've recently tackled the constructor problem , where various mixins classes that decorate each other (and a topmost host class) have different constructor signatures. 我最近解决了构造函数问题 ,其中相互装饰的各种mixins类(以及最顶层的宿主类)具有不同的构造函数签名。 To maintain a single constructor in the resulting decorated class, and without adding init functions, I've found the following solution. 为了在结果修饰的类中维护单个构造函数,并且不添加init函数,我找到了以下解决方案。 The only restriction it places on a mixin class is that if its constructor takes more than one parameter, they should all be encapsulated in a single tuple. 它对mixin类的唯一限制是,如果它的构造函数需要多个参数,它们都应该封装在一个元组中。 (Compiling this code with g++ requires the -std=c++0x flags) (用g ++编译此代码需要-std = c ++ 0x标志)

#include <boost/tuple/tuple.hpp>

// Base class for all mixins
struct Host {
    float f_;
    int i_;

    Host(float f, int i) : f_(f), i_(i) {}
};

// First mixin--constructs with 1 parameter
template <class B>
struct M1 : public B {
    char c_;

    template <class... A>
    M1(char c, const A&... a) : B(a...), c_(c) {}
};

// Second mixin--constructs with 3 parameters
template <class B>
struct M2 : public B {
    double d_;
    short s_;
    const char* p_;

    template <class... A>
    M2(boost::tuple<const char*, double, short> t, const A&... a)
    : B(a...), p_(t.get<0>()), d_(t.get<1>()), s_(t.get<2>()) {}
};


int main() {
    // ctor parameters go in this order, from most derived to base:
    M2<M1<Host>> tst(boost::make_tuple("test", 46.1, (short)-1), (char)5, 4.2f, 2);
  return 0;
}

My questions are: 我的问题是:
1) Is there a better, more elegant way of solving this problem with C++0X? 1)使用C ++ 0X有没有更好,更优雅的方法来解决这个问题?
2) Specifically, are tuples really necessary? 2)具体来说,元组真的有必要吗?

You only need something like tuples if you have multiple constructors with differing arity for the mixins (and thus ambiguities). 如果你有多个具有不同arity的构造函数(因此含糊不清),你只需要像元组这样的东西。

If not you could just handle the parameters for the mixin as usual: 如果不是,您可以像往常一样处理mixin的参数:

template <class... A>
M2(const char* p, double d, short s, const A&... a)
  : B(a...), p_(p), d_(d), s_(s) {}

You could construct the base struct and pass it as constructor parameter of M1 and M2, so they can call a copy constructor of b: 你可以构造基础结构并将其作为M1和M2的构造函数参数传递,这样它们就可以调用b的复制构造函数:

M2(const B &b, ....) : B(b), ....

Are you really sure you need inheritance? 你真的确定你需要继承吗? Composition is more elegant and maintainable. 构图更优雅,更易于维护。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM