Click here to Skip to main content
15,884,472 members
Articles / Programming Languages / C++11
Tip/Trick

Rvalue Member Functions and Overloading

Rate me:
Please Sign up or sign in to vote.
5.00/5 (8 votes)
10 Jul 2018CPOL2 min read 16.8K   10   4
Did you realize that the `*this` object can be qualified with lvalue vs rvalue? Here’s what you can do with that.

Introduction

Since 1989, you could specify modifiers for the *this object in the function signature, following the argument list.

C++
class C1 {
      ⋮
    int foo (int x);
    int foo (int x) const;

Declaring different exact types for this (C1* vs const C1*) is no different than what you do with any other argument with respect to overloading; it just puts the modifiers in a different place. In the example above, you will get the proper version of foo depending on the attributes of the object you are calling it on:

C++
void bar (const C1& source)
{
    C1 dest;
       ⋮
    int resultS = source.foo();  // const member called
    int resultD = dest.foo();    // non-const member called

In C++11, there is now another interesting attribute that can be applied to a parameter. Consider the functions:

C++
void demo (C1& param);
void demo (C1&& param);

You can overload based on whether a parameter is an lvalue or an rvalue. Again, this selects the version of the overloaded function based on the attributes of the parameter you are calling it on.

C++
C1 get_thing();
C1 me = get_thing();

demo (me);           // lvalue
demo (get_thing());  // rvalue

So naturally, this should extend to the implicit this object, right? Indeed, you can specify the type of the implicit object parameter in this manner (See n4659 §16.3.1 ¶4).

This allows for both overloading and control over calling context. Normally (without any & or && qualifier), a member function doesn’t care about the value category (lvalue or rvalue) of the object. But when you specify &, it then behaves like other parameters and variables of reference type, and refuses to bind non-const rvalues.

What You Can Do With This

Ensure Called on lvalue Only

Sometimes, a member function might be dangerous if called on a temporary instance. In particular, it might return a reference to internal state, or more generally, return a value whose lifetime must be a subset of the object it is obtained from.

C++
class P {
    std::string doctorial_thesis;
public:
    const std::string& get_text_1() const;
    const std::string& get_text_2() & const;
      ⋮
};

P load_P();

auto report = load_P().get_text_1();   // oops!
auto report = load_P().get_text_2();   // compile-time error

Ensure Called on rvalue

Think about the unique_ptr template. It must have some awareness of lvalue vs rvalue usage in order to allow or disallow certain operations, but this is done with the types of regular parameters. More generally, you can model the intended use case of a resource-returning object, including the implicit this parameter.

C++
auto handle = get_resource(id).release_raw();  // OK.

auto res = get_resource(id);
auto handle = res.release_raw();  // object `res` is now broken
res.do_something();  // BOOM!

Overload for Optimization

You can overload a function to avoid copying when possible, automatically. But, it is still correct in every possible usage.

C++
class P {
    std::string doctorial_thesis;
public:
    const std::string& get_text() & const
        {
           return doctorial_thesis; // copy the value
        }
    const std::string get_text() && const
        {  // note return is not a reference!
           return std::move(doctorial_thesis);  // eject the value that’s going to be destroyed anyway
        }
      ⋮
};

auto report = load_P().get_text();  // (initializing)  value moved into `report`
report = load_P().get_text();   // (assigning)  calls assignment operator, but no problem.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionThe order of ref and const should be swapped Pin
Member 145820696-Sep-19 23:21
Member 145820696-Sep-19 23:21 
QuestionYou might want to qualify this Pin
Mycroft Holmes10-Jul-18 14:12
professionalMycroft Holmes10-Jul-18 14:12 
Questionnot very clear for me Pin
michoubof9-Jul-18 21:57
michoubof9-Jul-18 21:57 
AnswerRe: not very clear for me Pin
Ajay Vijayvargiya15-Jul-18 20:22
Ajay Vijayvargiya15-Jul-18 20:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.