While working with ref-qualified function overloads, I'm getting different results from GCC (4.8.1) and Clang (2.9 and trunk). Consider the following code:
#include <iostream>
#include <utility>
struct foo
{
int& bar() &
{
std::cout << "non-const lvalue" << std::endl;
return _bar;
}
//~ int&& bar() &&
//~ {
//~ std::cout << "non-const rvalue" << std::endl;
//~ return std::move(_bar);
//~ }
int const& bar() const &
{
std::cout << "const lvalue" << std::endl;
return _bar;
}
int const&& bar() const &&
{
std::cout << "const rvalue" << std::endl;
return std::move(_bar);
}
int _bar;
};
int main(int argc, char** argv)
{
foo().bar();
}
Clang compiles it and outputs "const rvalue"
, while GCC thinks this is an ambiguous call with the two const-qualified functions both being best viable candidates. If I provide all 4 overloads, then both compilers output "non-const rvalue"
.
I would like to know which compiler --if any-- is doing the right thing, and what are the relevant standard pieces in play.
Note: The reason this actually matters is that the real code declares both const-qualified functions as constexpr
. Of course, there is no output to std::cout
and static_cast
is used instead of std::move
, so that they are valid constexpr
definitions. And since in C++11 constexpr
still implies const
, the overload commented out in the sample code cannot be provided as it would redefine the const-qualified rvalue overload.