2013-07-07 12 views
8

mam następujący program testowy:tymczasowej tablicy const nie wiąże się odniesienie rvalue

#include <iostream> 
#include <type_traits> 
#include <utility> 

template<typename Ty, std::size_t N> 
void foo(Ty (&&)[N]) 
{ 
    std::cout << "Ty (&&)[" << N << "]\t" << std::is_const<Ty>::value << '\n'; 
} 

template<typename Ty, std::size_t N> 
void foo(Ty (&)[N]) 
{ 
    std::cout << "Ty (&)[" << N << "]\t" << std::is_const<Ty>::value << '\n'; 
} 

template<typename Ty> 
using id = Ty; 

int main() 
{ 
    std::cout.setf(std::cout.boolalpha); 

    foo(id<int[]>{1, 2, 3, 4, 5}); 
    foo(id<int const[]>{1, 2, 3, 4, 5}); // <-- HERE. 
    int xs[]{1, 2, 3, 4, 5}; 
    foo(xs); 
    int const ys[]{1, 2, 3, 4, 5}; 
    foo(ys); 
    foo(std::move(xs)); 
    foo(std::move(ys)); 
} 

Spodziewam się, że linia oznaczona strzałką nazwałbym przeciążenie rvalue jak non-const rozmowy tuż nad nim, ale tak nie jest.

Czy to tylko błąd w GCC, czy jest coś w standardzie, które powoduje przeciążenie lwartością?

+0

Ciekawe, Clang dostaje to poprawnie i wywołuje przeciążenie rwartości. – Xeo

+0

Dobre pytanie: moje naiwne zrozumienie standardu zgadza się z twoim. [Live] (http://ideone.com/ErHuYO), jeśli chcesz zobaczyć wyjście. – Yakk

+0

Coś zabawnego dzieje się tutaj: http://ideone.com/ptTJ8i - moje 'const int' temporary traktowane jest jak' int && ', a nie' const int && '. – Yakk

Odpowiedz

2

Zgodnie ze standardem §12.2 [class.temporary]:

tymczasowych typu klasy są tworzone w różnych kontekstach wiązania odniesienie do prvalue (8.5.3), zwracając prvalue (6.6.3), A konwersja, która tworzy prvalue (4.1, 5.2.9, 5.2.11, 5.4), rzucając wyjątek (15.1), wprowadzając obsługę (15.3), oraz w niektórych inicjalizacjach (8.5).

Więc id<int const[]>{1, 2, 3, 4, 5} jest tymczasowy, a zatem jest prvalue §3.10 [basic.lval]:

rvalue (tzw historycznie, ponieważ rvalues ​​mogłyby pojawić się na bok prawy wyrażenia przypisania) jest xvalue, obiekt tymczasowy (12.2) lub jego podobiekt lub wartość, która nie jest powiązana z obiektem.

Wartość prinalue ("czysta" wartość r) to wartość r, która nie jest wartością x.

Dlatego należy wybrać funkcję przeciążoną z argumentem wartości rVue.

+0

Więc w zasadzie jest to błąd w GCC? – Mehrdad

+0

@Mebrad: Przypuszczam, że tak. Jak zauważył Xeo w swoim komentarzu, Clang zrozumiał to poprawnie. –

Powiązane problemy