Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inserting a variadic argument list into a vector?

Forgive me if this has been answered already, as I couldn't find it...

Basically I have an object that needs to take a variadic argument list in it's constructor and store the arguments in a vector. How do I initialize a vector from a the arguments of a variadic constructor?

class GenericNode { public:     GenericNode(GenericNode*... inputs) {             /* Something like... */         // inputs_.push_back(inputs)...; } private:     std::vector<GenericNode*> inputs_; }; 
like image 781
fredbaba Avatar asked Dec 20 '12 19:12

fredbaba


People also ask

What is variadic template in C++?

Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.

Can variadic methods take any number of parameters?

A variadic function allows you to accept any arbitrary number of arguments in a function.

What is variadic parameters in Golang?

A variadic function is a function that accepts a variable number of arguments. In Golang, it is possible to pass a varying number of arguments of the same type as referenced in the function signature.


1 Answers

The best thing would be to use an initializer list

#include <initializer_list> #include <vector> class GenericNode { public:     GenericNode(std::initializer_list<GenericNode*> inputs)          :inputs_(inputs) {} //well that's easy private:     std::vector<GenericNode*> inputs_; }; int main() {     GenericNode* ptr;     GenericNode node{ptr, ptr, ptr, ptr}; } //compilation at http://stacked-crooked.com/view?id=88ebac6a4490915fc4bc608765ba2b6c 

The closest to what you already have, using C++11 is to use the vector's initializer_list:

    template<class ...Ts>     GenericNode(Ts... inputs)          :inputs_{inputs...} {} //well that's easy too     //compilation at http://stacked-crooked.com/view?id=2f7514b33401c51d33677bbff358f8ae 

And here's a C++11 version with no initializer_lists at all. It's ugly, and complicated, and requires features missing from many compilers. Use the initializer list

template<class T> using Alias = T;  class GenericNode { public:     template<class ...Ts>     GenericNode(Ts... inputs) { //SFINAE might be appropriate          using ptr = GenericNode*;          Alias<char[]>{( //first part of magic unpacker              inputs_.push_back(ptr(inputs))              ,'0')...,'0'}; //second part of magic unpacker     } private:     std::vector<GenericNode*> inputs_; }; int main() {     GenericNode* ptr;     GenericNode node(ptr, ptr, ptr, ptr); } //compilation at http://stacked-crooked.com/view?id=57c533692166fb222adf5f837891e1f9 //thanks to R. Martinho Fernandes for helping me get it to compile 

Unrelated to everything, I don't know if those are owning pointers or not. If they are, use std::unique_ptr instead.

like image 128
Mooing Duck Avatar answered Sep 26 '22 02:09

Mooing Duck