From: alf.p.steinbach+usenet@gmail.com   
      
   On 03.04.2012 22:25, Daniel Krügler wrote:   
   > Am 03.04.2012 20:36, schrieb Kaba:   
   >> Have a look at the following code:   
   >>   
   >> class A   
   >> {   
   >> public:   
   >> A() {}   
   >> A(const A& that) {}   
   >> A(A&& that) {}   
   >> };   
   >>   
   >> template   
   >> void f(Type&& that)   
   >> {   
   >> A b(std::move(that));   
   >> }   
   >>   
   >> int main()   
   >> {   
   >> A a;   
   >> f(a); // Compiles.   
   >>   
   >> return 0;   
   >> }   
   >>   
   [snip]   
   >> I am feeling unease about the template moving from an lvalue as   
   >> something that might cause potential traps. What do you think of it?   
   >   
   > I tend to disagree. One needs to be aware that the "perfectly   
   > forwarding" signature has been introduced for a very specific reason:   
   > To forward any argument based on it's value category thus conserving   
   > the value category (at least to the level of xvalue vs. lvalue). If   
   > you are working with perfect forwarding signatures, you should   
   > *always* use std::forward, not std::move. With this rule in mind,   
   > there is only little that can go wrong.   
      
   Sorry, but I can't make any sense of that. Is e.g. unique_ptr's   
   constructor unique_ptr( unique_ptr&& ) to be interpreted as "perfectly   
   forwarding"? As I see it, even as just a default interpretation that's   
   utterly void of meaning or any practical advantage.   
      
      
   > Alternatively, if you don't want to have this effect, I suggest to   
   > constrain the function template to the value category you wish to   
   > accept. E.g. if f is supposed to accept *only* rvalues, this is easy   
   > to realize by imposing   
   >   
   > template   
   > typename std::enable_if::value>::type   
   > void f(Type&& that)   
   > {   
   > A b(std::move(that));   
   > }   
      
   Neither MSVC 10.0 nor MinGW g++ 4.6.1 accepted that code. As the g++   
   eror mesage put it, "two or more data types in declaration of 'f'". I am   
   sure you meant to write this instead:   
      
      
    template< class Type >   
    typename std::enable_if< !std::is_lvalue_reference::value,   
   void >::   
    type f(Type&& that)   
    {   
    A b(std::move(that));   
    }   
      
      
   However, I would suggest the in my view simpler and more direct   
      
      
    template< class Type >   
    void f( Type&& that)   
    {   
    A b(std::move(that));   
    }   
      
    template< class Type >   
    void f( Type& that ); // No way (lvalue => ambiguous).   
      
      
   which simply catches any lvalue actual argument with the second   
   signature, which (in that case) produces an ambiguity error, and just   
   for good measure is left unimplemented.   
      
   [snip]   
      
      
   Cheers & hth.,   
      
   - Alf   
      
      
   --   
    [ 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)   
|