Re: Internal move vs. copy in std::vector
On 2012-05-07 02:03, Wil Evers wrote:
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.
Note that this observation is based on a compiler that still does not
completely implement the C++11 standard. As of C++11 access "violations"
will be considered as part of "sfinae" conditions, that is a private
copy constructor of type X *should* have the effect that
std::is_copy_consructible<X>::value evaluates to false. For gcc 4.8 this
does currently not yet happen, because access control is not yet part of
sfiane. I do not know the corresponding state of other compilers, though.
Greetings from Bremen,
- Daniel
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]