В рамках продолжения изучения C++11.
Правильно ли я понимаю, что в производных классах теперь не нужно дублировать конструкторы базового класса, а можно написать один
Универсальный Конструктор:
template<class TData, class... Args>
Derived(TData&& rrDerivedData, Args&&... args)
: Base (std::forward<Args >(args)...),
m_strData(std::forward<TData>(rrDerivedData))
{
}
который первыми аргументами принимает параметры для своих данных, а параметры для базового класса передаются прямой передачей в виде вариадик хвоста? Или в таком подходе есть скрытые проблемы?
Update: кажется я нашёл одну: этот конструктор настолько универсальный, что перекрывает конструктор копирования. Значит аргументы самого класса Derived не должны быть шаблонными:
template<class... Args>
Data(std::string&& rrData, Args&&... args)
: Base (std::forward<Args >(args )...),
m_strData(std::move (rrData) )
{
}
| Скрытый текст |
| #include <iostream>
#include <stdlib.h>
#include <string>
class Base
{
public:
Base()
: m_n(0)
{
}
Base(int n, const std::string& strName, const std::string& strId)
: m_n (n ),
m_strName(strName),
m_strId (strId )
{
}
Base(const std::string& strName, const std::string& strId)
: m_n (0 ),
m_strName(strName),
m_strId (strId )
{
}
public:
int m_n;
std::string m_strName;
std::string m_strId;
};
class Data : public Base
{
public:
Data()
{
}
template<class TData, class... Args>
Data(TData&& rrData, Args&&... args)
: Base (std::forward<Args >(args )...),
m_strData(std::forward<TData>(rrData) )
{
}
public:
std::string m_strData; // before constructor
public:
template<class... Args>
Data(decltype(m_strData)&& rrData, Args&&... args)
: Base (std::forward<Args >(args )...),
m_strData(std::move (rrData) )
{
}
};
int main(int argc, char* argv[])
{
Data d1("data");
Data d2("data", 1, "name", "id");
Data d3("data", "name", "id");
Base b;
Data d4("data", b);
Base b2(2, "b2", "test");
Data d5("data", b2);
Base b3(2, "b2", "test");
Data d6("data", std::move(b3));
std::cout << "b3.m_strName = " << b3.m_strName << std::endl;
Data d7("data", d6);
Data d8(d7);
std::cout << "\n the end" << std::endl;
return 0;
}
|
| |
PS При множественном наследовании есть простой способ написать универсальный конструктор?