I have a question concerning this post:
Possibly even faster, especially for member types like std::string:
Code:
template <typename T>
typename std::vector<T>::iterator
fast_erase(std::vector<T> &vec, typename std::vector<T>::iterator it)
{
assert(it != vec.end());
std::iter_swap(it, vec.rbegin());
vec.pop_back();
return it;
}
It's not entirely clear to me how it would work for user-defined types (and would it really do the right thing for strings). Here's my little test program where only the last call to swap calls my "efficient" swap for class B.
Code:
#include <iostream>
#include <vector>
#include <algorithm>
class B
{
public:
B() {}
B(const B&) {std::cout << "B(const B&)\n";}
const B& operator= (const B&) {std::cout << "B::=\n"; return *this;}
void swap(B&) {std::cout << "B::swap\n";}
};
void swap(B& a, B& b)
{
a.swap(b);
}
int main()
{
std::vector<B> vec_b;
vec_b.push_back(B());
vec_b.push_back(B());
std::cout << "\niter_swap:\n";
std::iter_swap(vec_b.begin(), vec_b.begin()+ vec_b.size() - 1); //operator=
std::cout << "\nstd::swap:\n";
std::swap(vec_b.front(), vec_b.back()); //operator=
std::cout << "\nusign std::swap + swap:\n";
using std::swap;
swap(vec_b.front(), vec_b.back()); //operator=
std::cout << "\n::swap:\n";
::swap(vec_b.front(), vec_b.back()); //swap(B&, B&)
}