https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66672

            Bug ID: 66672
           Summary: std::is_same wrong result for captured reference value
                    inside a lambda
           Product: gcc
           Version: 5.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: thiago at kde dot org
  Target Milestone: ---

Given the following code:

====
#include <iostream>
#include <type_traits>

using namespace std;

int main()
{
  int i, &j = i;
  [=]
  {
    cout << is_same<decltype((j)), int      &>::value
         << is_same<decltype((j)), int const&>::value;
  }();
}
====
(trimmed from http://cppquiz.org/quiz/question/127)

With GCC 5.1, the code will print 10, but it should be 01. Clang 3.6, ICC 16
and MSVC 2015 do compile this as expected. The output 10 would be correct if
the extra set of parentheses weren't there.

The explanation given on the quiz website is:

> Since the expression for decltype is a parenthesized lvalue 
> expression, §7.1.6.2¶4 has this to say: "The type denoted by 
> decltype(e) is (...) T&, where T is the type of e;" As the
> expression occurs inside a const member function, the expression is
> const, and decltype((j)) denotes int const&. See also the example in 
> §5.1.2¶18.
[NB: it's paragraph 19 as of N4431]

The example in that paragraph of the standard matches almost exactly the code
above.

The output is correct with a functor:

====
struct S
{
  S(int &i) : j(i) {}
  void operator()() const
  {
    cout << is_same<decltype((j)), int      &>::value
         << is_same<decltype((j)), int const&>::value;
  };
  int j;    // captured by value
};
int main()
{
  int i;
  S{i}();
}
====

Reply via email to