在 g++ 下使用 std::vectors 的移动语义
我正在尝试在我的 VS2010 家庭副本上编写一个程序,以便在大学版本的 Fedora 上编译(Linux 版本 3.1.9-1.fc16.x86_64 ([电子邮件受保护])(gcc 版本 4.6.2 20111027(红帽 4.6.2-1)(GCC))
)。
该程序使用各种 c++11 功能,例如自动类型和移动构造函数。
一系列错误:
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/vector:63:0,
from src/OpenGL/Renderer.h:4,
from src/Wolfenstein3D2011.cpp:2:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_construct.h: In function ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = Wulf::MapWall, _Args = {const Wulf::MapWall&}]’:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_uninitialized.h:77:3: instantiated from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const Wulf::MapWall*, std::vector<Wulf::MapWall> >, _ForwardIterator = Wulf::MapWall*, bool _TrivialValueTypes = false]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_uninitialized.h:119:41: instantiated from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const Wulf::MapWall*, std::vector<Wulf::MapWall> >, _ForwardIterator = Wulf::MapWall*]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_uninitialized.h:259:63: instantiated from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<const Wulf::MapWall*, std::vector<Wulf::MapWall> >, _ForwardIterator = Wulf::MapWall*, _Tp = Wulf::MapWall]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_vector.h:280:9: instantiated from ‘std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = Wulf::MapWall, _Alloc = std::allocator<Wulf::MapWall>, std::vector<_Tp, _Alloc> = std::vector<Wulf::MapWall>]’
src/Map/Map.h:17:8: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_construct.h:76:7: error: no matching function for call to ‘Wulf::MapWall::MapWall(const Wulf::MapWall&)’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_construct.h:76:7: note: candidates are:
src/Map/MapWall.h:18:3: note: Wulf::MapWall::MapWall(Wulf::MapWall&&)
src/Map/MapWall.h:18:3: note: no known conversion for argument 1 from ‘const Wulf::MapWall’ to ‘Wulf::MapWall&&’
src/Map/MapWall.h:12:3: note: Wulf::MapWall::MapWall(Wulf::Direction)
src/Map/MapWall.h:12:3: note: no known conversion for argument 1 from ‘const Wulf::MapWall’ to ‘Wulf::Direction’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_construct.h: In function ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = Wulf::MapNode, _Args = {const Wulf::MapNode&}]’:
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_uninitialized.h:77:3: instantiated from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const Wulf::MapNode*, std::vector<Wulf::MapNode> >, _ForwardIterator = Wulf::MapNode*, bool _TrivialValueTypes = false]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_uninitialized.h:119:41: instantiated from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const Wulf::MapNode*, std::vector<Wulf::MapNode> >, _ForwardIterator = Wulf::MapNode*]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_uninitialized.h:259:63: instantiated from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<const Wulf::MapNode*, std::vector<Wulf::MapNode> >, _ForwardIterator = Wulf::MapNode*, _Tp = Wulf::MapNode]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_vector.h:280:9: instantiated from ‘std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = Wulf::MapNode, _Alloc = std::allocator<Wulf::MapNode>, std::vector<_Tp, _Alloc> = std::vector<Wulf::MapNode>]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_construct.h:76:7: instantiated from ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = std::vector<Wulf::MapNode>, _Args = {const std::vector<Wulf::MapNode>&}]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_uninitialized.h:77:3: instantiated from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::vector<Wulf::MapNode>*, std::vector<std::vector<Wulf::MapNode> > >, _ForwardIterator = std::vector<Wulf::MapNode>*, bool _TrivialValueTypes = false]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_uninitialized.h:119:41: instantiated from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::vector<Wulf::MapNode>*, std::vector<std::vector<Wulf::MapNode> > >, _ForwardIterator = std::vector<Wulf::MapNode>*]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_uninitialized.h:259:63: instantiated from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::vector<Wulf::MapNode>*, std::vector<std::vector<Wulf::MapNode> > >, _ForwardIterator = std::vector<Wulf::MapNode>*, _Tp = std::vector<Wulf::MapNode>]’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_vector.h:280:9: instantiated from ‘std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = std::vector<Wulf::MapNode>, _Alloc = std::allocator<std::vector<Wulf::MapNode> >, std::vector<_Tp, _Alloc> = std::vector<std::vector<Wulf::MapNode> >]’
src/Map/Map.h:17:8: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_construct.h:76:7: error: no matching function for call to ‘Wulf::MapNode::MapNode(const Wulf::MapNode&)’
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_construct.h:76:7: note: candidates are:
src/Map/MapNode.h:15:3: note: Wulf::MapNode::MapNode(Wulf::MapNode&&)
src/Map/MapNode.h:15:3: note: no known conversion for argument 1 from ‘const Wulf::MapNode’ to ‘Wulf::MapNode&&’
src/Map/MapNode.h:10:3: note: Wulf::MapNode::MapNode(Wulf::coord, Wulf::coord, Wulf::word, Wulf::word)
src/Map/MapNode.h:10:3: note: candidate expects 4 arguments, 1 provided
make: *** [obj/main.o] Error 1
这一切在 VS2010 中都没有问题,但是当我在 Linux 中编译它时(g++ -g -Wall -std=c++0x -pedantic
),我收到以下 Map.h:17 是 class Map {
,我不知道是什么原因造成的。
我能想象导致这种情况的唯一行是在 Map/Map.cpp 中,并且是
nodes[x].push_back(MapNode(x - halfwidth, y - halfheight, map[i], objs[i]));
和
walls.push_back(MapWall(air ? DIRECTION_WEST : DIRECTION_EAST));
这两个在 VS2010 下都工作得很好,成功地将临时数据移动到向量中,但显然在 g++ 下不行。
这是编译器的一些怪癖,还是我做错了什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
据我从错误消息中可以看出,您正在尝试复制
Map
,其中包含vector
,但失败是因为MapWall
不可复制。如果这些类型应该是可复制的,那么您需要向 MapWall 添加复制构造函数;您的用户声明的移动构造函数意味着不会隐式生成该构造函数。 (我可能会猜测 VS2010 错误地生成了一个;这可以解释为什么你的代码在那里工作)。
否则,您可能会发现通过向
Map
添加私有的、已删除的复制构造函数来跟踪恶意复制操作会更容易 - 然后您应该收到一条错误消息,准确显示正在尝试复制它的内容。As far as I can tell from the error messages, you are trying to copy a
Map
, which contains avector<MapWall>
, and this is failing becauseMapWall
is not copyable.If these types are supposed to be copyable, then you need to add a copy constructor to
MapWall
; your user-declared move constructor means that one won't be implicitly generated. (I might hazard a guess that VS2010 is incorrectly generating one; that would explain why your code works there).Otherwise, you might find it easier to track the rogue copy operation by adding a private, deleted copy constructor to
Map
- then you should get an error message showing you exactly what's trying to copy it.看到这些消息,我确信这是你的错,而 VS2010 太宽容了
This :
意味着你试图将 lreference 对象传递给移动构造函数或真正的构造函数。
接下来是同样的错误:
如果没有看到一些代码,就不可能知道你到底做了什么。
Seeing those messages, I am sure it's your fault, and VS2010 being too permisive
This :
means that you tried to pass lreference object to a move constructor, or the real constructor.
The same error is next :
Without seeing some code, it's not possible to tell what exactly you did.