使用 GCC 4.8 编译时无法对向量执行 std::swap
Cannot perform std::swap on a vector when compiling with GCC 4.8
我有一段用 C++11 编写的代码,可以在 VS2013 和 x86 上的 vs120 工具集上正常编译。现在,我正在尝试使用 GCC 4.8 工具集为 ARMv7 编译相同的代码,但出现以下错误:
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_contacts
是一个 std::vector<Collision>
而 i
是一个 for 循环的迭代器。 GCC 是否缺少某些东西,或者是否有特定于 GCC 的方法来做同样的事情?本质上,我想交换元素在 i
和最后一个元素的位置。
您正试图交换到迭代器,但传递的是右值作为两个参数:
m_contacts.begin() + i // an rvalue
m_contacts.end() // another rvalue
这不会编译,因为右值不能绑定到非 constlvalue 引用(VS 有一个 "extension" 允许这样做,这就是为什么您的代码可能会在该平台上编译,具体取决于编译器标志。)一般来说交换右值也没有多大意义。您需要做的是传递左值:
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());
如果你想交换元素,你将不得不取消引用迭代器(使用 *
)或使用 std::iter_swap()
。取消引用 container.end()
会导致未定义的行为,因此您的代码已损坏。请注意,MSVC 可能会接受该代码,因为它倾向于将临时值(返回值)转换为非常量引用,而兼容的编译器不会这样做。
我有一段用 C++11 编写的代码,可以在 VS2013 和 x86 上的 vs120 工具集上正常编译。现在,我正在尝试使用 GCC 4.8 工具集为 ARMv7 编译相同的代码,但出现以下错误:
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_contacts
是一个 std::vector<Collision>
而 i
是一个 for 循环的迭代器。 GCC 是否缺少某些东西,或者是否有特定于 GCC 的方法来做同样的事情?本质上,我想交换元素在 i
和最后一个元素的位置。
您正试图交换到迭代器,但传递的是右值作为两个参数:
m_contacts.begin() + i // an rvalue
m_contacts.end() // another rvalue
这不会编译,因为右值不能绑定到非 constlvalue 引用(VS 有一个 "extension" 允许这样做,这就是为什么您的代码可能会在该平台上编译,具体取决于编译器标志。)一般来说交换右值也没有多大意义。您需要做的是传递左值:
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());
如果你想交换元素,你将不得不取消引用迭代器(使用 *
)或使用 std::iter_swap()
。取消引用 container.end()
会导致未定义的行为,因此您的代码已损坏。请注意,MSVC 可能会接受该代码,因为它倾向于将临时值(返回值)转换为非常量引用,而兼容的编译器不会这样做。