templates - Initialization of member array with noncopyable non pod -


i think simple way ask due example. assume have following type:

class node {   // make noncopyable   node(const node& ref) = delete;         node& operator=(const node& ref) = delete;    // moveable   node(node&& ref) = default;   node& operator=(node&& ref) = default;    // not have default construction   node() = delete;   node(unsigned i): _i(i) {}    unsigned _i; }; 

now want store of these nodes in std::array:

template<unsigned count> class parentnode {   std::array<node,count> _children;   parentnode()       // cannt this, since not know how many nodes need      // : _children{{node(1),node(2),node(3)}}        : _children()  // how do this?   {} }; 

as stated in comment, question is: how do this? unsigned passed child should index of array child stored. more general solutions appreciated!

the following solution found myself might end in undefined behavior more complex types. proper defined solution see accepted answer.

template<unsigned count> class parentnode { public:    // return value implicitly invoke move operator/constructor    std::array<node,count> generatechildren(std::array<node,count>& childs)    {       (unsigned u = 0; u < count; u++)          childs[u] = node(u);  // use move semantics, (correct?)        return std::move(childs); // not needed       return childs;  // return value same return std::move(childs)    }    std::array<node,count> _children;    parentnode()       // cannt this, since not know how many nodes need      // : _children{{node(1),node(2),node(3)}}        : _children(generatechildren(_children))  // works because of move semantics (?)   {} };  parentnode<5> f;  

the code compile. not sure if expect do. maybe has insight in move semantics , rvalue references can add comments:-)

you can use variadics generate array elements initialized arbitrary function of indices. using standard machinery generating index sequences:

template <int... i> struct indices {}; template <int n, int... i> struct make_indices :   make_indices<n-1,n-1,i...> {}; template <int... i> struct make_indices<0,i...> : indices<i...> {}; 

it's straightforward:

template <typename t, typename f, int... i> inline std::array<t, sizeof...(i)> array_maker(f&& f, indices<i...>) {   return std::array<t, sizeof...(i)>{ std::forward<f>(f)(i)... }; }  template <typename t, std::size_t n, typename f> inline std::array<t, n> array_maker(f&& f) {   return array_maker<t>(std::forward<f>(f), make_indices<n>()); } 

which lets duplicating effect of std::iota:

auto = array_maker<int,10>([](int i){return i;}); 

to making array squares of first 10 natural numbers in reverse order:

const auto = array_maker<std::string,10>([](int i){   return std::to_string((10 - i) * (10 - i)); }); 

since node movable, allows define parentnode constructor as:

parentnode()     : _children(array_maker<node, count>([](unsigned i){return i+1;})) {} 

see put live @ coliru.


Comments

Popular posts from this blog

css - Which browser returns the correct result for getBoundingClientRect of an SVG element? -

gcc - Calling fftR4() in c from assembly -

Function that returns a formatted array in VBA -