[英]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
构造函数中指定的参数调用所有类。 Der1
和Der2
实际上继承自同一个 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.