首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我可以从基于范围的元素移动吗?

我可以从基于范围的元素移动吗?
EN

Stack Overflow用户
提问于 2016-11-18 03:37:11
回答 2查看 4.3K关注 0票数 7

假设我有这样的代码:

代码语言:javascript
复制
std::vector<std::string> produce(const std::string& str){
    // create a vector based on input
}

void consume(const std::string& str){
    for (auto i:produce(str))
        // do some thing that use the str
        // and I'd like to move it from the vector
        some_process(str) // for example, move into this function
}

我只是想知道编译器(我可以使用VS2015或gcc 6)是否可以优化以将元素移动到for-循环中。或者我该怎么做才能让它移动,因为字符串可能很长。

一个老的开始结束循环还是协同线有帮助?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-18 03:51:37

如果要将元素从该向量移动到some_function(),只需显式地执行move

代码语言:javascript
复制
void some_function( std::string str );
void some_function( std::string &&str ); // or explicitly


for(auto &i:produce(str))
    some_function( std::move(i) );

否则,不清楚将元素移动到for循环是什么意思。

票数 13
EN

Stack Overflow用户

发布于 2016-11-18 05:12:24

只要auto&有显式的std::move就足够了。

但是要花哨

代码语言:javascript
复制
struct empty_t{}; 
template<class It,class B=empty_t>struct range_t:B{
  It b,e;
  It begin()const{return b;}
  It end()const{return e;}
  range_t(It s,It f):b(std::move(s)),e(std::move(f)){}
  // fancy
  template<class S, class F>
  range_t(B base, S s, F f):B(std::move(base)),b(s(*this)),e(f(*this)){}
};
template<class It>range_t<It> range(It b, It e){return{std::move(b),std::move(e)};}
template<class B, class S, class F>
auto range( B base, S s, F f ){
  auto It=std::result_of_t<s(base)>;
  return range_t<It,B>{
    std::move(base),std::move(s),std::move(f)
  };
}
template<class R>
auto move_from(R& r){
  using std::begin; using std::end;
  return range( std::make_move_iterator(begin(r)), std::make_move_iterator(end(r)) ); 
}
template<class R>
auto move_from(R&& r){
  using std::begin; using std::end;
  return range(
    std::move(r),
    [](auto&r){return std::make_move_iterator(begin(r));},
    [](auto&r){return std::make_move_iterator(end(r));}
  ); 
}

现在,除了打字,

代码语言:javascript
复制
for(auto i:move_from(produce(str)))
  some_function( std::move(i) );

将使i成为每个元素的移动副本。

但这太疯狂了。

当您具有迭代基于ranfe/容器的代码时,这种技术可能很有用,您希望这些代码与移动无关。

代码语言:javascript
复制
template<class R, class F>
auto transform_to_vector( R&& r, F&& f ){
  using std::begin; using std::end;
  using rT=std::decay_t<std::result_of_t< f(*begin(std::forward<R>(r))) >>;
  std::vector<rT> retval;
  for(auto&& e:std::forward<R>(r)){
    retval.push_back( f(decltype(e)(e)) );
  }
  return retval;
}

现在,用move_from(x)作为您的“范围”调用上面的内容与用x调用它是不同的。你也可以想象其他算法也是这样写的。

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

https://stackoverflow.com/questions/40668949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档