Setting std :: vector in class constructor with different values ββfor element constructor
I have a class with a non-trivial constructor:
class mystream
{
public:
mystream(size_t buffersize,size_t index) : buffersize(buffersize),index(index){}
size_t buffersize;
size_t index;
};
An instance mystream
has a unique identifier corresponding to its position in the vector of the controlling class:
class mystreammanager
{
public:
mystreammanager() : streams(8,1024, /* WHAT TO DO HERE ??? */ )
{
}
std::vector<mystream> streams;
};
How can I construct a vector and initialize its elements with ascending value for the index?
source to share
Concise, clear and easy to debug the way to do this is to defer vector construction to a static class function:
class mystreammanager
{
public:
mystreammanager() : streams{ generate_streams(1024, 8) }
{
}
private:
static std::vector<mystream> generate_streams(size_t buffersize, size_t qty)
{
std::vector<mystream> result;
result.reserve(qty);
for(size_t i = 0 ; i < qty ; ++qty) {
result.emplace_back(buffersize, i);
}
return result;
}
std::vector<mystream> streams;
};
This is optimally effective because:
- RVO calls vector creation in place
- excluding list initialization means no redundant copies.
Compile time version :)
Required c++14
, but can certainly be adapted forc++11
#include <cstddef>
#include <vector>
#include <utility>
class mystream
{
public:
mystream(size_t buffersize,size_t index) : buffersize(buffersize),index(index){}
size_t buffersize;
size_t index;
};
template<size_t... Indexes>
std::initializer_list<mystream> mystream_maker_impl(std::index_sequence<Indexes...>)
{
return {{1024, Indexes}...};
}
template<size_t N>
std::initializer_list<mystream> mystream_maker()
{
return mystream_maker_impl(std::make_index_sequence<N>());
}
class mystreammanager
{
public:
mystreammanager() : streams(mystream_maker<8>())
{
}
std::vector<mystream> streams;
};
source to share
I used the answer from @RichardHodges as I was unhappy with my first choice. I came up with this pattern:
template<class T,class ...Args> std::vector<T> generate_with_index(size_t qty,Args ...args)
{
std::vector<T> result;
result.reserve(qty);
for(size_t i = 0 ; i < qty ; ++qty)
result.emplace_back(i, args...);
return result;
}
This helps me avoid redundancy. From a theoretical point of view, I like @ Drax's solution better, as it works most efficiently at compile time.
source to share