Fabian Knorr
Fabian Knorr

Reputation: 3184

Returning a forwarded reference

I want to build a maximum function that forwards the larger value to the result, keeping the type of reference (rvalue or lvalue).

#include <utility>

template<typename T>
constexpr T&& mmax(T&& left, T&& right) {
    return left > right ? std::forward<T>(left) : std::forward<T>(right);
}

int main() {
    mmax(1, 2);
}

However, this gives me

max.cc: In instantiation of 'constexpr T&& mmax(T&&, T&&) [with T = int]':
max.cc:9:14:   required from here
max.cc:5:72: warning: returning reference to temporary [-Wreturn-local-addr]
     return left > right ? std::forward<T>(left) : std::forward<T>(right);

Why is that? I'm using GCC 4.8.2 with -std=c++11.

Edit: This does not happen with clang++.

Upvotes: 3

Views: 238

Answers (1)

Kerrek SB
Kerrek SB

Reputation: 476950

Your original code should work, because of the rules about the conditional operator in C++ 11 5.16/4:

If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category

The two expressions forward<T>(left) and forward<T>(right) are either both lvalues or both xvalues, so they are always glvalues, and they are both of type T, and so the rule applies, and the type of the conditional expression should be of the same type and value category.

However, as a workaround for a potential compiler bug, you can use the following expression, which avoids figuring out the type and value category of the conditional expression (which seems to be where the bug is):

return std::forward<T>(left > right ? left : right);

Upvotes: 4

Related Questions