rvalue references and default constructors

Discussion in 'C++' started by Paul Brettschneider, Mar 26, 2008.

  1. Hello,

    C++0x introduces the concept of rvalue-references (described for example
    here: http://www.artima.com/cppsource/rvalue.html) and, if I got this
    right, an rvalue-reference is an invitation to mutilate the referenced
    object since it is a temporary which will not be used anymore. Which
    enables us to implement (amongst other things) move semantics.

    But, inside a function which gets an rvalue-reference it is treated like a
    normal reference, which makes sense since you don't want your object
    destroyed after accessing it once.

    std::move() will turn a normal (lvalue-)reference into an rvalue-reference.
    Therefore the idiomatic rvalue-copy-constructor and
    rvalue-assignment-operator will look like this:

    class Test : public Base {
    Object a;
    public:
    Test(Test &&t)
    : Base(std::move(t))
    , a(std::move(t.a))
    { };
    Test &operator=(Test &&t)
    {
    Base::eek:perator=(std::move(t));
    a = std::move(t.a);
    return *this;
    }
    };

    So my question is: will the rvalue-copy-constructor and the
    rvalue-copy-operator be automaticall generated or will we have to write it
    on our own?

    Thanks!
     
    Paul Brettschneider, Mar 26, 2008
    #1
    1. Advertising

  2. On 2008-03-26 09:08, Paul Brettschneider wrote:
    > Hello,
    >
    > C++0x introduces the concept of rvalue-references (described for example
    > here: http://www.artima.com/cppsource/rvalue.html) and, if I got this
    > right, an rvalue-reference is an invitation to mutilate the referenced
    > object since it is a temporary which will not be used anymore. Which
    > enables us to implement (amongst other things) move semantics.
    >
    > But, inside a function which gets an rvalue-reference it is treated like a
    > normal reference, which makes sense since you don't want your object
    > destroyed after accessing it once.
    >
    > std::move() will turn a normal (lvalue-)reference into an rvalue-reference.
    > Therefore the idiomatic rvalue-copy-constructor and
    > rvalue-assignment-operator will look like this:
    >
    > class Test : public Base {
    > Object a;
    > public:
    > Test(Test &&t)
    > : Base(std::move(t))
    > , a(std::move(t.a))
    > { };
    > Test &operator=(Test &&t)
    > {
    > Base::eek:perator=(std::move(t));
    > a = std::move(t.a);
    > return *this;
    > }
    > };
    >
    > So my question is: will the rvalue-copy-constructor and the
    > rvalue-copy-operator be automaticall generated or will we have to write it
    > on our own?


    Doing a quick search of the latest draft I found nothing about
    implicitly declared rvalue constructors.

    --
    Erik Wikström
     
    Erik Wikström, Mar 26, 2008
    #2
    1. Advertising

  3. Erik Wikström wrote:

    > On 2008-03-26 09:08, Paul Brettschneider wrote:
    >> Hello,
    >>
    >> C++0x introduces the concept of rvalue-references (described for example
    >> here: http://www.artima.com/cppsource/rvalue.html) and, if I got this
    >> right, an rvalue-reference is an invitation to mutilate the referenced
    >> object since it is a temporary which will not be used anymore. Which
    >> enables us to implement (amongst other things) move semantics.
    >>
    >> But, inside a function which gets an rvalue-reference it is treated like
    >> a normal reference, which makes sense since you don't want your object
    >> destroyed after accessing it once.
    >>
    >> std::move() will turn a normal (lvalue-)reference into an
    >> rvalue-reference. Therefore the idiomatic rvalue-copy-constructor and
    >> rvalue-assignment-operator will look like this:
    >>
    >> class Test : public Base {
    >> Object a;
    >> public:
    >> Test(Test &&t)
    >> : Base(std::move(t))
    >> , a(std::move(t.a))
    >> { };
    >> Test &operator=(Test &&t)
    >> {
    >> Base::eek:perator=(std::move(t));
    >> a = std::move(t.a);
    >> return *this;
    >> }
    >> };
    >>
    >> So my question is: will the rvalue-copy-constructor and the
    >> rvalue-copy-operator be automaticall generated or will we have to write
    >> it on our own?

    >
    > Doing a quick search of the latest draft I found nothing about
    > implicitly declared rvalue constructors.


    Me neither. And it makes me wonder, since given that this feature looks so
    obvious at a first glance, one would expect the standard to lose a word or
    two on why this will or will not be implemented, isn't it?
     
    Paul Brettschneider, Mar 26, 2008
    #3

  4. > So my question is: will the rvalue-copy-constructor and the
    > rvalue-copy-operator be automaticall generated or will we have to write it
    > on our own?


    Using gcc-4.3.0 it silenty(!) invokes the Test::eek:perator=(Test const&
    t) for

    Test a;
    Test b = std::move(a);
    Test c = std::moved(T());

    - if i disable the Test::eek:perator=(Test&& t) in source file.
    (But uses Test::eek:perator=(Test&& t) if it is availabled.)

    Though using std::move() might be considered to be an explicit request
    for rvalue reference argumented function.


    Moreover:
    One MUST use std::move(t) for explicit invocation of
    Base::eek:perator=(Base&& rhs) in Test::eek:perator=(Test&& t)

    Test &operator=(Test &&t)
    {
    Base::eek:perator=(std::move(t)); // HERE
    a = std::move(t);
    return *this;
    }

    Otherwise it calls Base::eek:perator=(Base const& rhs) silently again.

    Using member functions with rvalue reference arguments seems just to
    be a "fits better" for the compiler.
    Member functions with rvalue reference type arguments attract for
    applying actual rvalue references to some overloaded member function
    set - as forced by std::move().

    Worse in my view is, that inside those functions itself- which have
    rvalue reference arguments - those types are treated like lvalue
    references again (see the need for explicit std::move(t) in
    Test::eek:perator=(Test&& t).
    I guess the reason is that it MIGHT be given some lvalue reference as
    well - for invocation
    (For test you can also do the other way around: provide rvalue
    reference member functions and drop/disable the old "Test const& t"
    images.)
    So it falls back to that restriction level - unless you explicitly
    recover rvalue reference conditions (using std::move() again).
    This is feels like sapping type-safety.
    Or let me say: if i declare a rvalue reference argument for my member
    function i would like to keep treating it as rvalue reference inside
    that function.

    rgds!

    Frank
     
    Frank Bergemann, Apr 16, 2008
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kavya
    Replies:
    9
    Views:
    525
    Dik T. Winter
    Oct 28, 2006
  2. Chris Fairles
    Replies:
    1
    Views:
    376
    Howard Hinnant
    Sep 4, 2007
  3. Juha Nieminen
    Replies:
    13
    Views:
    633
    Edek Pienkowski
    Aug 29, 2012
  4. Michael Lehn
    Replies:
    3
    Views:
    281
    Michael Lehn
    Oct 3, 2012
  5. K. Frank
    Replies:
    4
    Views:
    186
Loading...

Share This Page