2013-07-07 3 views
8

나는 다음과 같은 테스트 프로그램이 있습니다임시 CONST 배열이를 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)); 
} 

내가 라인 바로 위에 const가 아닌 전화와 같은를 rvalue 과부하를 부를 것이다 화살표로 표시된 것으로 기대를하지만, 그렇지 않습니다.

이것은 GCC의 버그일까요? 아니면 lvalue 오버로드를 선택하게하는 표준에 뭔가가 있습니까?

+0

흥미 롭다면, Clang은 이것을 올바르게 받아서 rvalue overload를 호출합니다. – Xeo

+0

좋은 질문 : 표준에 대한 내 순진한 이해는 자신의 의견에 동의합니다. [라이브] (http://ideone.com/ErHuYO) 출력을보고 싶다면. – Yakk

+0

재미있는 일이 여기 있습니다 : http://ideone.com/ptTJ8i - 제 'const int'임시는'const int &&'가 아닌'int &&'처럼 취급되고 있습니다. – Yakk

답변

2

에 따르면 §12.2 [class.temporary] 표준 :

클래스 타입의 임시 변수는 다양한 상황에서 작성된

:하는 prvalue (6.6.3)를 반환하는 prvalue (8.5.3)에 을 참조 바인딩 (15.3) 예외를 던지고 핸들러 (15.3)를 입력하고 일부 초기화 (8.5)를 던져서 prvalue (4.1, 5.2.9, 5.2.11, 5.4)를 생성합니다.

그래서 id<int const[]>{1, 2, 3, 4, 5} 임시이며, 따라서 prvalue §3.10 [basic.lval]입니다 :

(우변은 할당 식의 오른쪽에 나타날 수 있기 때문에, 역사적라고 함)를 rvalue가있다 임시 개체 (12.2) 또는 그 하위 개체 또는 개체와 연결된 이 아닌 값.

prvalue ("순수"rvalue)는 xvalue가 아닌 rvalue입니다.

따라서 rvalue 참조 인수로 오버로드 된 함수를 선택해야합니다.

+0

기본적으로 GCC의 버그입니까? – Mehrdad

+0

@Mehrdad : 나는 그렇다고 생각합니다. Xeo가 그의 코멘트에서 지적한대로 Clang은이 사실을 알게되었습니다. –

관련 문제