2

I'm trying to construct a lambda that returns by const int, but the const qualifier is being discarded. In the following code, lam1 and lam3 are behaving as expected, but lam2 is not. Expected output is 0 1 1 but I get 0 0 1.

#include<type_traits>
#include<iostream>
using namespace std;

int main()
{
  int C{0};
  auto lam1 = [&]()->       int& {return C;};
  auto lam2 = [&]()-> const int  {return C;};
  auto lam3 = [&]()-> const int& {return C;};

  cout << is_const<remove_reference<decltype(lam1())>::type>::value << endl;
  cout << is_const<remove_reference<decltype(lam2())>::type>::value << endl;
  cout << is_const<remove_reference<decltype(lam3())>::type>::value << endl;
}

demo link: https://godbolt.org/z/xP4lYs

roro
  • 931
  • 5
  • 21

2 Answers2

3

It's intended. Remember that decltype returns the type of an expression, possibly with a reference qualifier to match the expression's value category. lam2 returns a prvalue, and well...

[expr]

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.

There are no const prvalues of primitive type. Since you return a const int, and that's the type of the function call expression, the const is removed prior to further analysis (including decltype deducing the type of the expression).

For class types, that is not the case, because the cv-qualifiers can affect a class object's behavior.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
0

Recall that it works this way for normal functions too.

That's by design, because returning built-ins by const value is pointless.

However, it is the decltype that is "removing" it (or, rather, allowing you to observe that it's removed when used in an expression) — the const is still part of the function's signature. If your example related to a class type rather than int, you might have observed something else (see previous link). :)

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055