manabreak
manabreak

Reputation: 5597

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

I have a piece of code written in C++11 that compiles fine on VS2013 and vs120 toolset on x86. Now, I'm trying to compile the same code for ARMv7 using GCC 4.8 toolset, but I get the following error:

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

Here's the line of code that produces this error:

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

m_contacts is a std::vector<Collision> and i is an iterator of a for-loop. Is there something I'm missing with GCC or is there a GCC-specific way to do the same thing? Essentially I want to swap the places of the element at i and the last element.

Upvotes: 0

Views: 177

Answers (2)

juanchopanza
juanchopanza

Reputation: 227390

You are attempting to swap to iterators, but are passing an rvalues as both arguments:

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

This won't compile because an rvalue can't bind to a non-constlvalue reference (VS has an "extension" that allows this, which is why your code might compile on that platform, depending on compiler flags.) It also doesn't make much sense to swap rvalues in general. What you need to do is pass lvalues:

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

Quite why you would want to swap iterators like this isn't clear. If you want to swap an element with the last element in the vector, you can use

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

Upvotes: 1

Ulrich Eckhardt
Ulrich Eckhardt

Reputation: 17415

If you want to swap elements, you will have to dereference the iterators (using *) or use std::iter_swap(). Dereferencing container.end() will cause undefined behaviour though, your code is therefore broken. Note than MSVC probably accepted the code because it tends to convert temporaries (returnvalues) to non-const references, which a compliant compiler doesn't.

Upvotes: 2

Related Questions