From: bouncer@dev.null   
      
   Daniel Krügler wrote:   
      
   > 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   
   >> #include   
   >>   
   >> 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 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::value evaluates to false.   
      
   That's good news to me; thanks for pointing it out. I found out later   
   that simply removing the private copy constructor declaration also   
   works, because the compiler will not generate a copy constructor (or   
   copy assignment operator) for a type with an explicitly declared move   
   constructor.   
      
   In that case, an attempt to call the copy constructor causes gcc-4.7.0   
   to report that because of the presence of the move constructor, the   
   copy constructor is implictly declared as deleted. To me, this seems   
   to be the most elegant approach.   
      
   Regards,   
      
   - Wil   
      
      
   --   
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
    [ comp.lang.c++.moderated. First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|