Impact of returning const value types in C++11 on move semantics
c++, c++11, constants, move-semantics
Solution
An expression calling a function that returns by value is a prvalue. However, there are no `const` prvalues of non-class non-array type (§5/6):
If a prvalue initially has the type “cv `T`,” where `T` is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to `T` prior to any further analysis.
This means that there's no difference between your two definitions of the function. Whether it returns a `const int` or just an `int` is irrelevant because the expression is never `const`.
However, there is a difference when you're returning a class type. Consider the following example:
struct foo
{
void bar() { std::cout << "Hello" << std::endl; }
};
foo get_foo();
Now, if we call `get_foo()`, we get a temporary `foo` object. This prvalue is not `const` and we can call non-`const` member functions on it, so we could happily do `get_foo().bar()`. However, we can change the declaration of `get_foo` like so:
const foo get_foo();
Now, the expression `get_foo()` is a `const` prvalue (which is allowed because it is a class type) and we cannot call `bar` on the temporary object returned by it any more.
Nonetheless, it doesn't make sense to talk about move semantics for a non-class type, as an `int` is never moved from. If you return a `const` class type, that can also not be moved from because it is `const`. To demonstrate:
foo get_foo();
foo f(get_foo()); // Will call the move constructor
const foo get_foo();
foo f(get_foo()); // Will call the copy constructor
This is because a `const` prvalue won't bind to a non-`const` rvalue reference, which is what the move constructor takes as its argument.
Problem
I'm not clear on the impact that returning `const` values has on move semantics in C++11. Is there any difference between these two functions, which return data members? Is `const` still redundant in C++11? ``` int GetValueA() { return mValueA; } const int GetValueB() { return mValueB; } ``` What about for these functions? ``` int GetValuesAB() { return mValueA + mValueB; } const int GetValuesCD() { return mValueC + mValueD; } ```