I am trying to implement a Mixin class, and facing some problems:
This is what I have at the moment:
#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;
}
I want all the classes to be called with the parameters specified in the MixinVisitor constructor.
Der1 and Der2 inherit virtually from the same Base class.
The code I have now compiles with Clang, but fails with GCC. The behavior with Clang is not what I expect though, as I see as output only the default constructor being called.
Gcc error is as follows:
prog.cc:44:68: error: invalid use of pack expansion expression
44 | MixinVisitor(Args&&... args) : Mixin(std::forward<Args>(args)...)...
| ^~~
1
Moreover the output is not what I am expecting, and that might be due to virtual inheritance.
I only see the default ctor being called:
default ctor
4204112
How can I force the proper constructor to be called?
edit: thank to the comments, there's a workaround for the gcc problem:
MixinVisitor(Args&&... args) : Mixin{std::forward<Args>(args)...}...
however I'd still like to know why the correct constructor is not called