Search code examples
c++constantsvalue-categories

Why do cv-qualifiers get removed from function return type in some cases?


Look at this simple example:

template <typename T>
const T const_create() {
    return T();
}

struct Foo { };

int main() {
    auto &x = const_create<Foo>(); // compiles
    // auto &x = const_create<int>(); // doesn't compile
}

Why does the version with Foo compile, but with int doesn't? In other words, why does const get removed from the return type of const_create<int>? It works like if it returned int, not const int. Isn't this an inconsistency in the language?

Where does the standard mandate this behavior?


Solution

  • [expr]/6 says:

    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.

    Therefore, the const Foo prvalue is just const Foo, but const int prvalue is adjusted to int.


    This rule is introduced in C++14 (compare N3337 [basic.lval]/4 with N4140 [expr]/6) by CWG 1261.