繁体   English   中英

Mixin 构造函数嵌套包扩展

[英]Mixin constructors nested pack expansion

我正在尝试实现一个 Mixin class,并面临一些问题:

这就是我目前所拥有的:

#include <iostream>
#include <string>

using namespace std;

struct Base
{
    Base()
    {
        cout << "default ctor" << endl;
    }
    
    Base(int i, string s)
        :i_(i)
            ,s_(s)
    {
        cout << "i: " << i << " s:" << s << endl;
    }
    virtual ~Base() = default;
    virtual void handle() {};
    
    int i_;
    string s_;
};

struct Der1 : virtual public Base
{
    using Base::Base;
};

struct Der2 : virtual public Base
{
    using Base::Base;
};

template<class... Mixin>
class MixinVisitor : public Mixin... {
public:
  template <typename... Args>
  MixinVisitor(Args&&... args) : Mixin(std::forward<Args>(args)...)...
  {
  }

};



int main()
{
    MixinVisitor<Der1, Der2> m(10, "var");
    cout << m.i_ << endl;
}

我希望使用MixinVisitor构造函数中指定的参数调用所有类。 Der1Der2实际上继承自同一个 Base class。

我现在使用 Clang 编译的代码,但使用 GCC 编译失败。 Clang 的行为不是我所期望的,因为我看到 output 只调用了默认构造函数。

Gcc 错误如下:

prog.cc:44:68: error: invalid use of pack expansion expression
   44 |   MixinVisitor(Args&&... args) : Mixin(std::forward<Args>(args)...)...
      |                                                                    ^~~
1

此外,output 不是我所期望的,这可能是由于虚拟 inheritance。

我只看到调用了默认的ctor:

default ctor
4204112

如何强制调用正确的构造函数?

编辑:感谢评论,gcc 问题有一个解决方法:

  MixinVisitor(Args&&... args) : Mixin{std::forward<Args>(args)...}...

但是我仍然想知道为什么不调用正确的构造函数

GCC 错误invalid use of pack expansion expression是一个错误#88580 似乎是 GCC 10 中的回归。

如评论中所述,将:Mixin(std::forward<Args>(args)...)...更改为:Mixin{std::forward<Args>(args)...}...解决了问题。

关于为什么调用默认的Base构造函数:虚拟基类的构造函数直接被最派生类的构造函数调用。 在这种情况下, MixinVisitor直接调用Base构造函数,由于你没有提到调用哪一个,所以调用的是默认的。 这就是虚拟 inheritance 的工作原理(另请参阅常见问题解答)。

如果您想调用Base(int i, string s) ,请明确指定它,例如:

template<class... Mixin>
class MixinVisitor : public Mixin... {
public:
  template <typename... Args>
  MixinVisitor(Args&&... args)
      : Base(std::forward<Args>(args)...), Mixin{std::forward<Args>(args)...}...
  {
  }

  . . .

我不知道您的具体用例,但虚拟基地通常是一个非常基本的样板 class 和默认 ctor,以免不必要地限制使用。 这样,mixin 可以具有不依赖于基础的 ctor。

暂无
暂无

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

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