在 g++ 下使用 std::vectors 的移动语义

发布于 2024-12-28 03:09:27 字数 8194 浏览 1 评论 0 原文

我正在尝试在我的 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++ 下不行。
这是编译器的一些怪癖,还是我做错了什么?

I'm attempting to get a program written on my home copy of VS2010 to compile on the university's version of Fedora (Linux version 3.1.9-1.fc16.x86_64 ([email protected]) (gcc version 4.6.2 20111027 (Red Hat 4.6.2-1) (GCC) ) ).
The program uses various c++11 features such as auto types and move constructors.
This all works no trouble in VS2010, but when I compile it in linux (g++ -g -Wall -std=c++0x -pedantic), I get the following slew of errors:

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

Since Map/Map.h:17 is class Map {, I've got no idea what's causing this.
The only lines I can imagine as causing this are in Map/Map.cpp and are
nodes[x].push_back(MapNode(x - halfwidth, y - halfheight, map[i], objs[i]));
and
walls.push_back(MapWall(air ? DIRECTION_WEST : DIRECTION_EAST));
Both of these work fine under VS2010, successfully moving the temporary into the vector, but obviously not under g++.
Is this some quirk of the compiler, or have I done something wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

盗梦空间 2025-01-04 03:09:27

据我从错误消息中可以看出,您正在尝试复制 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 a vector<MapWall>, and this is failing because MapWall 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.

梦旅人picnic 2025-01-04 03:09:27

看到这些消息,我确信这是你的错,而 VS2010 太宽容了

This :

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)

意味着你试图将 lreference 对象传递给移动构造函数或真正的构造函数。

接下来是同样的错误:

no known conversion for argument 1 from ‘const Wulf::MapWall’ to ‘Wulf::MapWall&&’

如果没有看到一些代码,就不可能知道你到底做了什么。

Seeing those messages, I am sure it's your fault, and VS2010 being too permisive

This :

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)

means that you tried to pass lreference object to a move constructor, or the real constructor.

The same error is next :

no known conversion for argument 1 from ‘const Wulf::MapWall’ to ‘Wulf::MapWall&&’

Without seeing some code, it's not possible to tell what exactly you did.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文