Variadic Templates - problem z konstruktorem

0

Mam taki testowy kod:

class Master;

class Base
{
public:
	Master& M;
	int A, B, C;
	Base(Master& m, int a, int b, int c) : M(m), A(a), B(b), C(c)
	{
		std::cout << A << std::endl;
		std::cout << B << std::endl;
		std::cout << C << std::endl;
	}
};

class Derived : public Base
{
public:
	template<typename... Arguments>
	Derived(Arguments... A) :
		Base(A...)
	{
	}
};

class Master
{
public:
	virtual void Test() = 0;
};

class MasterNext : public Master
{
public:
	Derived derived;
	MasterNext() :
		derived(*this, 10, 20, 30)
	{
	}
};

class MasterFinal : public MasterNext
{
public:
	void Test() override
	{
	}
};

int main()
{
	MasterFinal MF;
	return 0;
}

Nie kompiluje się i wywala błąd 'Master': cannot instantiate abstract class. Gdy natomiast podmienię konstruktor w klasie Derived na bezszablonowy i wtedy działa bez problemu

class Derived : public Base
{
public:
	Derived(Master& m, int a, int b, int c) : 
		Base(m, a, b, c)
	{
	}
};

Próbowałem rzutowania, ale bezskutecznie:

template<typename T>
class MasterNext : public Master
{
public:
	Derived derived;
	MasterNext() :
		derived(static_cast<Master&>(*this), 10, 20, 30)
	{
	}
};

Jestem pewien, że chodzi o coś drobnego, ale nie mogę tego rozgryźć. Ten konstruktor koniecznie musi być jako variadic template. Ktoś potrafi coś doradzić? Z góry dziękuję.

6
    template<typename... Arguments>
    Derived(Arguments... A) :
        Base(A...)
    {
    }

Przyjmujesz parametry przez kopię, zmień na:

    template<typename... Arguments>
    Derived(Arguments&&... A) :
        Base(A...)
    {
    }

PS: ten konstruktor musisz obwarować sfinae/enable ifami/(konceptami?), albo będzie łapał też Derived(Derived&&) i Derived(Derived const&)

0

Pomogło, dziękuję :). Za radę odnośnie konstruktorów również.

4
kq napisał(a):

Przyjmujesz parametry przez kopię, zmień na:

    template<typename... Arguments>
    Derived(Arguments&&... A) :
        Base(A...)
    {
    }

PS: ten konstruktor musisz obwarować sfinae/enable ifami/(konceptami?), albo będzie łapał też Derived(Derived&&) i Derived(Derived const&)

Tak dokładniej, to powinno być tak:

    template<typename... Arguments>
    Derived(Arguments&&... a) :
        Base(std::forward<Arguments>(a)...)
    {
    }

To się nazywa "perfect forwarding".

1 użytkowników online, w tym zalogowanych: 0, gości: 1