0
#include <iostream> template <class T> void print_type() { std::cout << __PRETTY_FUNCTION__ << std::endl; } int main () { float x, &r = x; std::cout << "capture by value" << std::endl; [=] { print_type<decltype(x)>(); print_type<decltype((x))>(); print_type<decltype(r)>(); print_type<decltype((r))>(); }(); std::cout << "capture by reference" << std::endl; [&] { print_type<decltype(x)>(); print_type<decltype((x))>(); print_type<decltype(r)>(); print_type<decltype((r))>(); }(); } 

The output of clang 10.0 is (GCC 10.0 has a bug):

capture by value void print_type() [T = float] void print_type() [T = const float &] void print_type() [T = float &] void print_type() [T = const float &] capture by reference void print_type() [T = float] void print_type() [T = float &] void print_type() [T = float &] void print_type() [T = float &] 

I wonder why decltype((x)) and decltype((r)) have a const qualifier when they are captured by value. When they are captured by reference, they don't have a const qualifier.

Any idea?

And what's the common use case of decltype((variable)) inside and outside lambda?

Edit#1:

Few flagged this as a duplicate of this.

The post doesn't explain why double parenthesis adds const to decltype's deduction.

7
  • 1
    Does this answer your question? Lambda: Why are captured-by-value values const, but capture-by-reference values not? or C++0x lambda capture by value always const?, etc. Commented Jul 12, 2020 at 9:01
  • "GCC 10.0 has a bug" What bug? Commented Jul 12, 2020 at 9:02
  • @underscore_d added the link to the bug report. Commented Jul 12, 2020 at 9:05
  • @underscore_d thanks for your links. both links pointed out when lambda is captured by value without mutable, we should think it as operator()() const and the value captured as a non static variable. However, those 2 links don't explain why using double parenthesis will add const quantifier to the reference type. Commented Jul 12, 2020 at 9:10
  • 1
    @KamilCuk ? Neither conversion is relevant... decltype(variable) is different from decltype((variable)) because decltype directly depends on the syntax of its argument expression. The mention of decltype in your quote says "stuff like int f(int); int *p = nullptr; decltype(f(*p)) x = 0; doesn't crash, even though f(*p) looks like it calls for the lvalue-to-rvalue conversion (i.e. read) of *nullptr". decltype of an rvalue expression gives either T&& or T (for xvalues or prvalues, resp.) None of the decltypes are on rvalues. Commented Jul 12, 2020 at 9:35

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.