Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Named Return Value Optimization when using std::optional

I recently discovered std::optional as a way to improve the clarity of my code, especially for return value of functions. However I had questions about its impact on performance. More specifically I wanted to know if it was possible to write a code similar to the one below that would allow the compiler to apply Named Return Value Optimization.

struct Data
{
    int x;
    int y;
};

std::optional<Data> makeData(bool condition)
{
    Data data;

    if(condition)
    {
        data.x = 2.0;
        data.y = 2.0;

        return data;
    }
    else
    {
        return {};
    }
}
like image 437
Romain D. Avatar asked Nov 15 '19 21:11

Romain D.


People also ask

Are there any optimizations related to return values?

There are 2 optimizations related to return value: To understand these optimizations, consider the object at call site being assigned the value returned by a function (returning by value):

What is an optional value in C++?

std::optional The class template std::optional manages an optional contained value, i.e. a value that may or may not be present. A common use case for optional is the return value of a function that may fail.

How do you write a function that optionally returns an object?

This article on std::optional is the first of a series that will examine each of the vocabulary types in turn. How do you write a function that optionally accepts or returns an object? The traditional solution is to choose one of the potential values as a sentinel to indicate the absence of a value:

What happens when an optional object is contextually converted to bool?

When an object of type optional<T> is contextually converted to bool, the conversion returns true if the object contains a value and false if it does not contain a value. The optional object contains a value in the following conditions:


1 Answers

Well, in this case, the as-if rule is enough already: Data is trivially copyable and trivially destructible, so you cannot observe whether the compiler copies it, or whether it directly constructs it into the std::optional<Data> return object. NRVO is not needed in order to prevent the copy.

Let's suppose you gave Data a copy constructor with a side effect. Then the question of whether NRVO applies would be relevant. The answer is no: NRVO doesn't apply, because the local variable's type differs from the function return type. In order to allow NRVO to happen, you might write something like this:

std::optional<Data> r;
if (condition) {
    r.emplace();
    r.x = 2.0;
    r.y = 2.0;
}
return r;
like image 95
Brian Bi Avatar answered Oct 17 '22 00:10

Brian Bi