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

发布于 2024-09-12 10:45:07 字数 1406 浏览 18 评论 0原文

我最近解决了构造函数问题,其中相互装饰的各种 mixins 类(以及最顶层的主机类)有不同的构造函数签名。为了在生成的装饰类中维护单个构造函数,并且不添加 init 函数,我找到了以下解决方案。它对 mixin 类的唯一限制是,如果其构造函数采用多个参数,则它们应该全部封装在一个元组中。 (使用 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;
}

我的问题是:
1) 有没有更好、更优雅的方法用 C++0X 解决这个问题?
2)具体来说,元组真的有必要吗?

I've recently tackled the constructor problem, where various mixins classes that decorate each other (and a topmost host class) have different constructor signatures. To maintain a single constructor in the resulting decorated class, and without adding init functions, I've found the following solution. 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. (Compiling this code with g++ requires the -std=c++0x flags)

#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?
2) Specifically, are tuples really necessary?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一刻暧昧 2024-09-19 10:45:07

如果您有多个具有不同混合数量的构造函数(因此存在歧义),那么您只需要像元组这样的东西。

如果没有,你可以像往常一样处理 mixin 的参数:

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

You only need something like tuples if you have multiple constructors with differing arity for the mixins (and thus ambiguities).

If not you could just handle the parameters for the mixin as usual:

template <class... A>
M2(const char* p, double d, short s, const A&... a)
  : B(a...), p_(p), d_(d), s_(s) {}
那小子欠揍 2024-09-19 10:45:07

您可以构造基本结构并将其作为 M1 和 M2 的构造函数参数传递,以便它们可以调用 b 的复制构造函数:

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

您真的确定需要继承吗?组合更加优雅且易于维护。

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:

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

Are you really sure you need inheritance? Composition is more elegant and maintainable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文