C ++ 11/VS2010:返回不可复制但可移动对象的容器 [英] C++11 / VS2010 : Returning containers of uncopyable but movable objects

查看:101
本文介绍了C ++ 11/VS2010:返回不可复制但可移动对象的容器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

#include <vector>
#include <boost/noncopyable.hpp>

struct A : private boost::noncopyable
{
  A(int num, const std::string& name)
    : num(num),
      name(name)
  {
  }

  A(A&& other)
    : num(other.num),
      name(std::move(other.name))
  {
  }

  int num;
  std::string name;
};

std::vector<A> getVec()
{
  std::vector<A> vec;
  vec.emplace_back(A(3, "foo"));
  // vec.emplace_back(3, "foo"); not available yet in VS10?

  return vec; // error, copy ctor inaccessible
}

int main ( int argc, char* argv[] )
{
  // should call std::vector::vector(std::vector&& other)
  std::vector<A> vec = getVec();

  return 0;
}

这在VS2010下无法编译,因为显然Anoncopyable,因此无法复制std::vector<A>.因此,我无法从函数返回std::vector<A>.

This does not compile under VS2010 because obviously A is noncopyable and thus std::vector<A> cannot be copied. Accordingly I cannot return a std::vector<A> from a function.

但是,考虑到RVO的概念,这种事情对我来说是不合适的.如果在此处应用了返回值优化",则可以省略复制构造,并且对getVec()的调用将是有效的.

However it doesn't feel right to me that this sort of thing is not possible considering the concept of RVO. If Return Value Optimization was applied here, copy construction could be omitted and the call to getVec() would be valid.

那么执行此操作的正确方法是什么?在VS2010/C ++ 11中完全有可能吗?

So what would be the proper way to do this? Is this possible at all in VS2010 / C++11?

推荐答案

如果return vec;无法编译,则VS2010尚不完全支持移动语义.通常,如果从函数返回,则自动隐式移动变量.使用return std::move(vec);作为临时替代方法,并记下您的脑海,以免日后删除std::move.

If return vec; does not compile, VS2010 does not support move semantics fully yet. Normally, automatic variables are moved implicitly if returned from a function. Use return std::move(vec); as an interim workaround, and make a note in your head to get rid of the std::move in the future.

在此常见问题解答答案的标题为移出功能"下,可以找到完整说明.

A full explanation can be found in this FAQ answer under the headline "Moving out of functions".

此外,您的两个参数的构造函数将复制字符串参数的副本,该副本将由reference-to-const传递.我建议改用值代替参数并将其移入成员:

Also, your two-argument constructor makes a copy of the string argument which is passed by reference-to-const. I would suggest taking the argument by value instead and moving it into the member:

A(int num, std::string name) : num(num), name(std::move(name)) { }

这样,您可以减少所需副本的数量.参见想要速度吗?按值传递以获取详细信息.

This way, you minimize the number of necessary copies. See Want Speed? Pass by Value for details.

此外,由于您的move构造函数没有做任何特殊的事情,因此您可以default它:

Also, since your move constructor doesn't do anything special, you can default it:

A(A&& other) = default;

这使得它在面对变化时更加强大.错误很少会隐藏在您不编写的代码中:)

This makes it more robust in the face of changes. Bugs seldomly hide in the code you don't write :)

这篇关于C ++ 11/VS2010:返回不可复制但可移动对象的容器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆