gpt4 book ai didi

c++ - 为什么我不能在一个序列中放置多个元素?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:39:37 24 4
gpt4 key购买 nike

C++11 引入了 emplace 函数来在序列中就地构造元素。这是对复制或移动元素的 insert 的补充。

但是,在 insert 的多个重载中,只有单个元素插入版本,

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

有一个emplace版本,

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

有什么理由不允许使用 emplace 就地构造 n 元素吗?

当重载时,

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

就像对应的insert

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

可能与其他重载冲突,将构造函数参数作为 元组,或使用一些特殊标记(如 in_place_t)可能会消除它们的歧义。

编辑vector 提议的函数 emplace_n 可能具有如下所示的行为

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};
}

最佳答案

问题是没有简单的方法来确定一个元素的参数何时结束以及下一个元素的参数何时开始。您可以通过 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 加上一个迭代器来标记插入位置是很危险的。这是因为 emplaceemplace_back 可以使迭代器无效(至少对于 vector 而言),然后函数不知道如何获得新的迭代器到你想要的位置。

Demo here .

关于c++ - 为什么我不能在一个序列中放置多个元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22248466/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com