It is often seen that examples of using STL algorithms are illustrated by containers with list initialization, such as:
std::vector< int > v{1, 2, 3, 4};
But when this approach is used for (heavy) classes (as opposed to ints), it implies excessive copy operations from them, even if they are passed by rvalue (moved to), because the std::initializer_listexample above only provides const_iterators.
To solve this problem, I use the following approach (C ++ 17):
template< typename Container, typename ...Args >
Container make_container(Args &&... args)
{
Container c;
(c.push_back(std::forward< Args >(args)), ...);
return c;
}
auto u = make_container< std::vector< A > >(A{}, A{}, A{});
But this becomes unsatisfactory when I do the following:
A a;
B b;
using P = std::pair< A, B >;
auto v = make_container< std::vector< P > >(P{a, b}, P{std::move(a), std::move(b)});
(, A B , ), , undefined ++. :
template< Container >
struct make_container
{
template< typename ...Args >
make_container(Args &&... args)
{
(c.push_back(std::forward< Args >(args)), ...);
}
operator Container () && { return std::move(c); }
private :
Container c;
};
A a; B b;
using P = std::pair< A, B >;
using V = std::vector< P >;
V w = make_container< V >{P{a, b}, P{std::move(a), std::move(b)}};
, , - , .
? , ? ( ++ 11, ++ 14, ++ 1z)?