I have a matrix class (the element type is Y
) that has, along with other constructors, the following constructor:
matrixT(
size_type rows, // The number of rows
size_type cols // The number of columns
) :
boost::numeric::ublas::matrix<Y>(rows, cols)
{
}
(I use boost BLAS for the actual implementation, but that's not relevant here).
I need a std::vector<matrixT>
of this (for Y
a double
), and I know how many elements I need; n
, say. I also know all the sizes in advance; all have rows
rows and cols
columns
I'd like to do something like
std::vector<matrixT> vec(n, std::emplace(rows, cols))
as I'd like to avoid taking deep copies of such matrices. My understanding is I can do something to force the constructor to be called; which is what std::emplace(rows, cols)
is there for.
However I can't get the syntax correct. Any ideas? Do I need to use std::initialiser_list
?
(If my terminology is incorrect then please feel free to let me know, or edit the question).
There's no need for std::vector
to have such a constructor.
It already provides a method called emplace_back
. The arguments of emplace_back
should match the arguments of one of your constructors.
vec.emplace_back(rows, cols)
called n
times will achieve what you want without taking a deep copy of the matrix. You could even reserve
vector storage in advance.
( std::initializer
list - note the spelling - is used for brace initialisation ; a different topic).
Here is an emplace_n
and emplace_create_vector
:
template<class... Ts,class...Args>
void emplace_n( std::vector<Ts...>& vec, size_t n, Args&&... args ) {
if (vec.capacity() < vec.size() + n ) {
vec.reserve( (std::max)(vec.capacity()*3/2, vec.size()+n) );
}
for (size_t i = 1; i < n; ++i) {
vec.emplace_back(args...);
}
if (n)
vec.emplace_back(std::forward<Args>(args)...);
}
template<class...Ts,class...Args>
std::vector<Ts...> emplace_create_vector( size_t n, Args&&... args ) {
std::vector<Ts...> retval;
emplace_n( retval, n, std::forward<Args>(args)... );
return retval;
}
This lets you create an n-element vector via emplacement, instead of copying.
std::vector<matrixT> vec = emplace_create_vector<matrixT>(n, rows, cols);
and it does so reasonably efficiently.
Every vector
copy above will be elided by any acceptable C++ compiler, and no copy or move constructor of matrixT
is called.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.