Why can't I replace multiple elements in a sequence?

In C ++ 11, a function was introduced emplaceto build an element within a sequence. It complements insertthat either copies or moves elements.

However, from multiple overloads insert, only the insert version of one item,

i.e.

iterator insert( const_iterator p, T const& x);
iterator insert( const_iterator p, T&& x );

It has a version emplace,

template< class... Args > 
iterator emplace(const_iterator p, Args&&... x);

Is there any reason rather than allowing the creation of elements nin place with emplace?

While overload, for example,

template< class... Args > 
iterator emplace(const_iterator p,size_type n,Args&&... x);

like the corresponding insert

iterator insert(const_iterator p,size_type n,const_reference x);

may conflict with another overload by accepting constructor arguments as tupleor using some special tag, for example in_place_t, which can eliminate them.

    emplace_n vector ,

template<class... Args>
iterator emplace_n(const_iterator p,size_type n,Args&&... x)
{
    size_type const offset = p - begin();
    if(capacity() < size()+n)
    {
        vector<T> v;
        v.reserve(size()+n);
        v.assign(make_move_iterator(begin(),make_move_iterator(end());
        swap(*this,v);
    }
    auto const sz = size();
    for(auto c = 0; c != n ; ++c)
    {
        emplace_back(x...); //can do forward only if n == 1
    }
    rotate(begin()+offset,begin()+sz,end());
    return iterator{begin() + offset};
}
+4
2

, , . tuple, pair , ​​ :

template<int... Is>
struct index_seq { };

template<int N, int... Is>
struct make_index_seq : make_index_seq<N - 1, N - 1, Is...> { };

template<int... Is>
struct make_index_seq<0, Is...> : index_seq<Is...> { };

template<class Cont, class Tup, int... Is>
void emplace_back_impl(Cont& c, Tup&& tup, index_seq<Is...>)
{
    using std::get;
    c.emplace_back(get<Is>(std::forward<Tup>(tup))...);
}

template<class Cont, class... Tups>
void emplace_multiple(Cont& c, Tups&&... tups)
{
    int const unpack[]{
        0, ((emplace_back_impl)(c, std::forward<Tups>(tups),
                                make_index_seq<
                                    std::tuple_size<typename std::remove_reference<Tups>::type>{}
                                >()), 0)...
    };
    static_cast<void>(unpack);
}

emplace_multiple :

std::vector<std::string> xs;
emplace_multiple(xs, std::make_tuple("Hello, world!"), std::make_tuple(10, 'a'));

, emplace_back. emplace , . , emplace emplace_back ( , vector s), , .

.

+2

emplace_n, - n . emplace , ( ) , . "" :

vector<X> vx;
vector<X>::const_iterator it = ... ;

vx.emplace_2(it, a1, a2, a3, a4, a5);

, , ? , . " " :

auto it2 = vx.emplace_2(it);
vx.emplace(it2, a1, a2, a3, a4, a5);

//or
auto it2 = vx.emplace_2(it, a1);
vx.emplace(it2, a2, a3, a4, a5);

//or
auto it2 = vx.emplace_2(it, a1, a2);
vx.emplace(it2, a3, a4, a5);

... . n > 2 .

"" . - emplacer-iterator std::transform pf multiple-emplace.

+1

Source: https://habr.com/ru/post/1530583/


All Articles