21

I am looking at 8.4.4.1 in n4713 C++ standard:

void f() {
float x, &r = x;
[=] {
   decltype(x) y1; // y1 has type float
   decltype((x)) y2 = y1; // y2 has type float const& because this lambda is not mutable and x is an lvalue
   decltype(r) r1 = y1; // r1 has type float&
   decltype((r)) r2 = y2; // r2 has type float const&
};
}

The standard says r2 has type float const&, and then I tried to print out the types:

#include <iostream>

template <class T>
void print_type() {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

int main () {
    float x, &r = x;
    [=] {
        print_type<decltype(x)>();
        print_type<decltype((x))>();
        print_type<decltype(r)>();
        print_type<decltype((r))>();
    }();
}

It gave:

void print_type() [with T = float]
void print_type() [with T = const float&]
void print_type() [with T = float&]
void print_type() [with T = float&]

The type of r2 is float& instead of float const&. Did I do something wrong?

I used g++ 8.3.1 to compile. I also tried 9.1.0 but same thing.

2
  • 11
    gcc bug. Couldn't find a dupe, so filed 96095.
    – Barry
    Commented Jul 7, 2020 at 15:06
  • 4
    @Barry I believe this bug is the same issue. It has been around for a while.
    – ioums
    Commented Jul 7, 2020 at 15:21

1 Answer 1

1

As the question already mentions, the type of decltype((r)) must be float const& according to the standard since we are in not-mutable lambda.

GCC incorrectly prints type of decltype((r)) in your example. Clang and Visual Studio process your example correctly.

And even GCC has the issue only with type printing, it does not allow the user to change the value referenced by r or to initialize float & reference from r:

int main () {
    float x = 0, &r = x;
    [=]() {
        [[maybe_unused]] decltype((r)) q = r;
    }();
}

https://gcc.godbolt.org/z/9oKzoeaq9

Not the answer you're looking for? Browse other questions tagged or ask your own question.