Есть ли общий способ пересылки аргументов конструктора?

У меня есть работа Cloneable/CloneableImpl классная пара ниже. Это делает свою работу, пока у меня есть конструкторы по умолчанию от дочернего к родительскому.

Предположим, конструктор Animal изменен на Animal( std::string const& name ), которому нужно передать имя от конструкторов дочерних классов.

Как я могу включить это требование в структуру при сохранении Cloneable/CloneableImpl общий?

Другими словами, мне нужно иметь возможность передавать все аргументы конструктора от Lion, Tiger до Animal. Есть ли способ сделать это в C ++ 11 в общем виде?

Если это невозможно, как можно реструктурировать эти шаблоны, чтобы они оставались общими, учитывая требования конструктора?

Код

template<typename P>
struct Cloneable
{
virtual P* clone() const = 0;
};

template<typename T,typename P>
struct CloneableImpl :
public P
{
virtual P* clone() const
{
return new T( dynamic_cast<T const&>(*this));
}
};

// ----------------------------------------------------------------------------

struct Animal :
public Cloneable<Animal>
{
};

struct Lion  :
public CloneableImpl<Lion,Animal>
{
};

struct Tiger :
public CloneableImpl<Tiger,Animal>
{
};

int
main( int argv, char* argc[] )
{
Animal* x = new Lion;
Animal* y = x->clone();

// we want to do this without hard-coding in template classes
// Animal* z = new Lion( "Samba" );
}

9

Решение

После @ Cheersandhth.-Альф и @R. Предложения Мартино Фернандеса в комментариях к ФП рассмотреть идеальная пересылка. Я немного исследовал и придумал это, которое, кажется, работает.

Спасибо, парни!

КОД

#include <string>
#include <iostream>

template<typename P>
struct Cloneable
{
virtual P* clone() const = 0;
};

template<typename T,typename P>
struct CloneableImpl :
public P
{
template<typename... Args>
CloneableImpl( Args&&... args )
: P(std::forward<Args>(args)...)
{  }

virtual P* clone() const
{
return new T( dynamic_cast<T const&>(*this));
}
};

// ----------------------------------------------------------------------------

struct Animal :
public Cloneable<Animal>
{
Animal( std::string const& name ) : m_name( name ) { }

std::string  m_name;
};

struct Lion  :
public CloneableImpl<Lion,Animal>
{
template<typename... Args>
Lion( Args&&... args )
: CloneableImpl<Lion,Animal>(std::forward<Args>(args)...)
{  }
};

struct Tiger :
public CloneableImpl<Tiger,Animal>
{
};

int
main( int argv, char* argc[] )
{
Animal* x = new Lion( "Samba" );
Animal* y = x->clone();

std::cerr << y->m_name << std::endl;
}
9

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector