Наследование частного конструктора CRTP с помощью объявления друзей - PullRequest
0 голосов
/ 23 ноября 2018

У меня проблемы с пониманием правильного поведения наследующих конструкторов из базового класса.В моем конкретном случае у меня есть базовый класс crtp с частными конструкторами, чтобы предотвратить создание базового класса (как абстрактного класса).Теперь crtp-base оказывает поддержку производному классу, а производный класс наследует конструкторы базового класса с помощью оператора using.Это хорошо работает для конструктора по умолчанию, копирования и перемещения, но не работает для пользовательских конструкторов.Есть ли способ достичь этого без повторного использования всех конструкторов в производном классе?

#include <iostream>

template <typename d_t>
class base
{
    friend d_t;

    base()
    {
        std::cout << "base: ctor()\n";
    }
    base(base const & other) = default;
    base(base && other) = default;

    base(int)
    {
        std::cout << "base: ctor()\n";
    }
};

class derived: public base<derived>
{
public:

   using base<derived>::base;
};

int main()
{
   derived d{};
   derived d1{d};
   derived d2{std::move(d1)};
   // derived d3{1};  //does not compile!
}

EDIT

AFAIK cppreference говорит, что доступностьКонструкторы не изменяются спецификатором доступа объявления using в производном классе, который отличается от других функций-членов.Но я видел подобный код, который компилируется и запускается, и я не уверен, правильно ли я понял объявление об использовании.Конечно, я изучу другой код дальше, чтобы увидеть, что происходит, но я хотел знать, есть ли что-то скрытое, что я мог бы пропустить.

1 Ответ

0 голосов
/ 23 ноября 2018

Короткий ответ - да, просто опубликуйте их в базовом классе.Унаследованные конструкторы имеют такую ​​же доступность в производном классе, как и в базе.Невозможно сделать публичный конструктор частного класса общедоступным в производном классе.

Но абстрактные базовые классы не могут быть созданы в любом случае сами по себе.Нет необходимости делать их конструкторы частными.

CRTP не имеет никакого отношения к любому из вышеперечисленного.Если вам нужно только это для объявления friend, то вы можете обойтись без шаблона.

class base
{
public:
  base()
  {    
  }

  base(int)
  {
    std::cout << "base: ctor()\n";
  }

  virtual void foo() = 0;
};

class derived: public base
{
public:
  using base::base;

  void foo() override
  {
    // details...
  }
};

int main()
{
  derived d{};
  derived d1{d};
  derived d2{std::move(d1)};
  derived d3{1};  //Works!!
}

Дальнейшее чтение по cppreference: Using-декларация

...