#include <iostream>
using namespace std;
template<typename T>
void f(T&&) { cout << "f(T&&)" << endl; }
template<typename T>
void f(const T&&) { cout << "f(const T&&)" << endl; }
struct A {};
const A g1() { return {}; }
const int g2() { return {}; }
int main()
{
f(g1()); // outputs "f(const T&&)" as expected.
f(g2()); // outputs "f(T&&)" not as expected.
}
The issue description is embedded in the code. My compiler is clang 5.0
.
I just wonder:
Why does C++ treat built-in types and custom types differently in such a case?
I don't have a quote from the standard, but cppreference confirms my suspicions:
A non-class non-array prvalue cannot be cv-qualified. (Note: a function call or cast expression may result in a prvalue of non-class cv-qualified type, but the cv-qualifier is immediately stripped out.)
The returned const int
is just a normal int
prvalue, and makes the non-const overload a better match than the const
one.