Универсальный конструктор
От: B0FEE664  
Дата: 07.07.16 13:03
Оценка:
В рамках продолжения изучения 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 При множественном наследовании есть простой способ написать универсальный конструктор?
И каждый день — без права на ошибку...
Отредактировано 07.07.2016 13:52 B0FEE664 . Предыдущая версия . Еще …
Отредактировано 07.07.2016 13:50 B0FEE664 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.