Помогите разобраться variadic templates

136
22 июня 2019, 06:10

Покажите пожалуйста простой пример с variadic templates. Хотелось бы следующее

(Добавил деструктор)

class IAnimal{
public:
   virtual ~IAnimal() {}
   virtual void fuu() = 0;
};
class Animal : public IAnimal{
public:
   Animal(){}
   void fuu(){}
};
template<class... anyClass>
class Farm{
public:
    Farm(anyClass... arg){
    //Как поместить список аргументов конструктора в вектор.
}
private:
std::vector<IAnimal*> vec;
};
int main(){
    IAnimal* dog = new Animal();
    IAnimal* cat = new Animal();
    Farm<IAnimal*, IAnimal*> obj(dog,cat);
    delete cat; 
    delete dog; 
}

Или я не понимаю чего то важного.

Answer 1

Ну, мне кажется, раз тип точно задан - к чему возня с шаблонами?

class IAnimal{
public:
    virtual void fuu() = 0;
};
class Animal : public IAnimal{
public:
    Animal(){}
    void fuu(){}
};
class Farm
{
public:
    Farm(initializer_list<IAnimal*> l):vec(l.begin(),l.end())
    {
    }
private:
    std::vector<IAnimal*> vec;
};
int main(){
    IAnimal* dog = new Animal();
    IAnimal* cat = new Animal();
    Farm obj {dog,cat};
}

См. https://ideone.com/7cPzVB

Answer 2

Если вы хотите идти именно по этому пути, то просто

Farm(anyClass... arg) : vec{ arg... } {}

и все. Или, для вашего случая, возможно лучше

Farm(anyClass *... arg) : vec{ arg... } {}

При этом в C++17 ваш класс получит неявный deduction guide, который позволит вам объявлять объекты как

Farm obj(dog, cat);

т.е. без явного указания шаблонных аргументов.

http://coliru.stacked-crooked.com/a/e7acbb9e506f8e66

Однако я не вижу необходимости в такой неограниченной гибкости в вашем коде, где вектор все равно жестко прописан как вектор IAnimal *. Я бы сказал, что вариант с std::initializer_list из ответа @Harry тут более уместен.

Answer 3
  1. В вектор помещается вот так:

    (vec.push_back(arg), ...);
  2. Память за собой очищать надо.

  3. Отсутствие виртуального деструктора вызовет UB при удалении.

Код полностью (с исправлениями): https://ideone.com/tcbHKl

#include <iostream>
#include <vector>
using namespace std;
class IAnimal {
public:
  virtual ~IAnimal() {}
  virtual void fuu() = 0;
};
class Animal : public IAnimal {
public:
  Animal(){}
  void fuu(){}
};
template<class... anyClass> class Farm {
public:
  Farm(anyClass... arg) {
    (vec.push_back(arg), ...);
  }
private:
  std::vector<IAnimal*> vec;
};
int main() {
  IAnimal* dog = new Animal();
  IAnimal* cat = new Animal();
  Farm<IAnimal*, IAnimal*> obj(dog,cat);
  delete cat;
  delete dog;
}
READ ALSO
Не работает чтение и запись в файл Qt

Не работает чтение и запись в файл Qt

Есть окно, в окне кнопка и лейблкод кнопки

141
Как убрать eventHandler с кнопки в javafx?

Как убрать eventHandler с кнопки в javafx?

при таком коде во время запуска игры по идее должно пропадать действие при нажатии кнопкиБез добавления eventHandler игра не реагирует, но вот...

120
Почему веб приложения не зависимы от ос [закрыт]

Почему веб приложения не зависимы от ос [закрыт]

Заранее извиняюсь за вопросСкорее всего он глупы и некорректный

124
Исключение при загрузке FXML файлов

Исключение при загрузке FXML файлов

Изучаю JavaFX, столкнулся с такой проблемой, не могу прогрузить FXML файлы, выдает Exception in Application start method, жалуясь на строку, где происходит загрузка...

158