http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51547

             Bug #: 51547
           Summary: auto, type deduction, reference collapsing and const:
                    invalid initialization of reference of type 'const
                    X&&' from expression of type 'const X'
    Classification: Unclassified
           Product: gcc
           Version: 4.6.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: tud...@fb.com


Created attachment 26074
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26074
g++ -E output

The following program fails to compile using g++ 4.6.2 (g++ -std=c++0x)

#include <vector>

struct Bar {
  int x;
};

struct Foo {
  const std::vector<Bar>& bar() const {
    return bar_;
  }

  std::vector<Bar> bar_;
};

template <class X>
struct Y {
  void foo() {
    Foo a;
    auto b = a.bar().begin();
    auto&& c = b->x;
  }
};

template <class X>
void foo() {
  Foo a;
  auto b = a.bar().begin();
  auto&& c = b->x;
}


int main() {
  Y<int> p;
  p.foo();
  foo<int>();
}

a.cpp: In member function ‘void Y<X>::foo() [with X = int]’:
a.cpp:34:9:   instantiated from here
a.cpp:20:19: error: invalid initialization of reference of type ‘const int&&’
from expression of type ‘const int’
a.cpp: In function ‘void foo() [with X = int]’:
a.cpp:35:12:   instantiated from here
a.cpp:28:17: error: invalid initialization of reference of type ‘const int&&’
from expression of type ‘const int’

The program compiles correctly if Y or foo() are non-templates.

Reference collapsing should deduce "auto&& c" as "const int&", and it appears
to do so in the non-template case.

Note that this bug is very brittle to reproduce (I tried to reduce it to remove
the use of std::vector, but I couldn't) -- for example, replacing "b->x" with
"(*b).x" makes the code compile correctly.

Attaching the preprocessor output (g++ -std=c++0x -E)

Reply via email to