使用 GCC 4.8 编译时无法对向量执行 std::swap

Cannot perform std::swap on a vector when compiling with GCC 4.8

本文关键字:向量 执行 std swap GCC 编译 使用      更新时间:2023-10-16

我有一段用 C++11 编写的代码,在 x86 上的 VS2013 和 vs120 工具集上编译得很好。现在,我正在尝试使用 GCC 7 工具集为 ARMv4.8 编译相同的代码,但出现以下错误:

no matching function for call to 
'swap(__gnu_cxx::__normal_iterator<Collision*, std::vector<Collision> >, std::vector<Collision>::iterator)

下面是产生此错误的代码行:

std::swap(m_contacts.begin() + i, m_contacts.end());

m_contactsstd::vector<Collision>i是for循环的迭代器。GCC 是否缺少一些东西,或者是否有特定于 GCC 的方法来做同样的事情?本质上,我想交换元素在i和最后一个元素的位置。

如果要

交换元素,则必须取消引用迭代器(使用*)或使用std::iter_swap()。取消引用container.end()会导致未定义的行为,因此您的代码被破坏了。请注意,MSVC 可能接受该代码,因为它倾向于将临时引用(返回值)转换为非常量引用,而兼容的编译器不会。

您正在尝试交换到迭代器,但将右值作为两个参数传递:

m_contacts.begin() + i // an rvalue
m_contacts.end()       // another rvalue

这不会编译,因为右值无法绑定到非 constlvalue 引用(VS 有一个允许这样做的"扩展",这就是为什么你的代码可能会在该平台上编译,具体取决于编译器标志。一般来说,交换右值也没有多大意义。您需要做的是传递左值:

auto a = m_contacts.begin() + i;
auto b = m_contacts.end();
std::swap(a, b); 
为什么

你想要像这样交换迭代器尚不清楚。如果要将元素与向量中的最后一个元素交换,可以使用

auto a = m_contacts.begin() + i;
std::swap(*a, m_contacts.back());