Re: Internal move vs. copy in std::vector
Nikolay Ivchenkov wrote:
On 29 Apr, 23:59, Dave Abrahams <d...@boostpro.com> wrote:
on Sat Apr 28 2012, Wil Evers <bouncer-AT-dev.null> wrote:
Dave Abrahams wrote:
vector reallocation should use move operations when T's copy
constructor is noexcept and copy operations otherwise.
You probably meant
vector reallocation should use move operations when T's _move_
constructor is noexcept and copy operations otherwise.
Right?
Exactly right. Thanks for catching the mistake.
That still seems to be wrong. Vector reallocation should use move
operations when T's move constructor has a non-throwing exception
specification or the call to T's copy constructor would not be well-
formed when considering immediate context; otherwise it should use
T's copy constructor.
struct X
{
X(X &&) {}
X(X const &); // has no definition in the program
};
I experimented a little bit with gcc-4.7.0, and FWIW, I did run into a
surprise when adding move semantics to a C++-98-style noncopyable
type. This is what I tried:
#include <iostream>
#include <vector>
class elem {
public :
elem() { }
elem(elem&&) { std::cout << "elem(elem&&)" << std::endl; }
private :
// Disable copying (C++98 style)
elem(const elem&); // not defined
};
int main()
{
std::vector<elem> vec;
vec.emplace_back();
vec.reserve(vec.capacity() + 1);
return 0;
}
This caused the compiler to complain that elem's copy constructor is
not accessible. (The actual instantiation traceback is quite
interesting, but I'll leave that out for now.) Because elem's move
constructor may throw, the compiler insists on using the copy
constructor - even though it is inaccessible.
To get the code to compile, one has to either decorate the move
constructor with 'nothrow', or the copy constructor with '= delete'.
I wonder how many C++ users will understand which of these to pick,
and when.
- Wil
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]