Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >从另一个容器创建容器,在c++中应用每个元素的一些功能

从另一个容器创建容器,在c++中应用每个元素的一些功能
EN

Stack Overflow用户
提问于 2014-02-21 11:22:22
回答 3查看 607关注 0票数 6

我的问题很简单,参见示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::array<int,6> a = {{0,1,2,3,4,5}}; // -- given container.
auto F = []( int i ) { return  i*i; }; // -- given function.

std::vector<int> v;  // need create

// my solution:
v.reserve( a.size () );
for( std::size_t i = 0; i < a.size(); ++i )
    v.push_back( F(a[i]) ); 



// but I need something like
   std::vector<int>v( a.begin(), a.end(), <|applying each element to F|> );

我可以创建像上面这样的容器,而不是显式调用预订和任何重新分配吗?

编辑

  1. 我想避免保留;因为其他情况下,我的第一个解决方案对我有好处:)
  2. 我希望避免任何大小调整;因为默认情况下每个元素都是初始化的。
  3. 我将在真正的项目中使用这个项目,其中可能包括许多第三方库( boost,Soft,.)。
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-02-21 11:32:28

另一个解决方案是使用boost::transform_iterator。好处是您可以将迭代器传递给容器构造函数。这避免了与使用std::back_inserter或在目标上调用reserveresize时相比的内存重新分配。所有这些都是在一份声明中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::vector<int> result(
      boost::make_transform_iterator(std::begin(a), F)
    , boost::make_transform_iterator(std::end(a), F)
    );

不过,您可以实现更简洁的语法,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::vector<int> result(transform_range(a, F));

transform_range实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
template<class Iterator>
struct AutoSequence
{
    Iterator const beg_, end_;

    template<class T>
    operator std::vector<T>() const {
        return {beg_, end_};
    }
};

template<class Function, class InSeq>
auto transform_range(InSeq const& in) -> AutoSequence<decltype(boost::make_transform_iterator<Function>(in.begin()))> {
    return {
          boost::make_transform_iterator<Function>(std::begin(in))
        , boost::make_transform_iterator<Function>(std::end(in))
        };
}

template<class Function, class InSeq>
auto transform_range(InSeq const& in, Function&& f) -> AutoSequence<decltype(boost::make_transform_iterator(in.begin(), f))> {
    return {
          boost::make_transform_iterator(std::begin(in), f)
        , boost::make_transform_iterator(std::end(in), f)
        };
}
票数 2
EN

Stack Overflow用户

发布于 2014-02-21 11:23:59

标准算法std::transform正是这样做的!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::vector<int> v(a.size());
std::transform(
   std::begin(a), std::end(a),
   std::begin(v),
   F
);

如果您愿意,可以从空向量开始并使用std::back_inserter

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
std::vector<int> v;
std::transform(
   std::begin(a), std::end(a),
   std::back_inserter(v),
   F
);

但是如果你这样做,你就会让自己受到不必要的重新分配(除非你先做reserve,就像你最初的尝试一样)。你可以自己决定你的首要任务是什么。

票数 12
EN

Stack Overflow用户

发布于 2014-02-21 11:23:53

使用std::transform

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <algorithm> // std::transform
#include <iterator>  // std::back_inserter

....

transform(a.begin(), a.end(), back_inserter(v), F);

您可能需要首先调用v.reserve(asize()),以避免重新分配。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21943387

复制
相关文章

相似问题

添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文