2012-06-30 7 views
1

다음 코드의 컴파일 오류가 발생합니다. 나는 심지어 임시 객체가 const 참조에 바인딩 될 것을 기대하고있다. 그래서 그것이 유효한 코드가되어야 궁금하네요. 그러나 g ++은 나에게이 에러를 준다. clang은 그런 에러를주지 않을 것이다. 아무도 이것이 왜 일어나는 정확한 이유를 알려주지 않습니까?g ++ : 임시 객체 인 경우 컴파일이 참조 배열을 추론하지 못했습니다.

#include <iostream> 

struct TestClass 
{ 
    TestClass() : str() 
    { 
     strncpy(str, "hello", sizeof(str)); 
    } 

    char str[6]; 

    char (&getStr())[6] 
    { 
     return str; 
    } 
}; 

template <typename T> 
void printFunc(const T& str) 
{ 
    std::cout << str << std::endl; 
} 

int main() 
{ 
    TestClass obj; 
    printFunc(obj.str); 
// printFunc(TestClass().str); // <- This line gives compilation error. 
    printFunc(TestClass().getStr()); 
    return 0; 
}; 
+0

나중에 참조 할 수 있도록 게시물에 코드를 넣으려면 html 태그를 사용하지 말고 그냥 모두 선택하고 '{}'버튼을 누르십시오. 또는'{}} 버튼이하는 것과 같은 4 칸 (보통 코드 들여 쓰기)으로 들여 쓰기하십시오. –

+2

g ++ 4.7.1은 오류를주지 않습니다. 그러나 구형 g ++에서는 오류가 발생합니다. http://ideone.com/263aT – nims

+0

정말입니까? 나는 g ++를 사용했고 어떤 에러도 내지 않았다. – Gabi

답변

4

나는 가정 것이라고 TestClass().str를 rvalue 배열 (C 및 C++ 언어 모두에서 매우 이국적인 일이)라는 사실을 통해 GCC 여행의 버전. initailizer가 의 값인 일 때 참조 초기화의 구체적인 내용이 잘못 구현되었습니다. 분명히이 버그는 이후 버전에서 수정되었습니다.

한편, obj.strTestClass().getStr()은 모두 lvalue 어레이입니다. 직접 참조 바인딩의 직접적인 규칙에 따라 처리되므로 문제가 발생하지 않습니다. 당신이

template <typename T> printFunc(const T str) 

에 크게 변경됩니다 상황을 함수 템플릿을 수정하는 경우

:

는 코멘트를 해결하기 위해. 이제 더 이상 참조 바인딩 문제가 아닙니다. 이제는 배열 - 포인터 변환 규칙이 적용됩니다.

원래 버전에서 Tchar [6]으로,이 새에서는 char *으로 추론되었습니다. 인수가 함수에 전달되면 배열 유형이 완전히 손실됩니다. 대신 포인터가 전달됩니다. 이렇게하면 참조 바인딩의 원래 문제가 완전히 제거되고 배열의 lvalue-ness 또는 rvalue-ness에 관계없이 코드가 컴파일됩니다.

예를 들어 기능 내에 sizeof str을 인쇄하여 두 버전의 차이점을 관찰 할 수 있습니다. 원본은 배열 크기를 바이트 (6)로 인쇄하고, 새로운 것은 포인터 크기 (ideone의 플랫폼의 경우 4)를 인쇄합니다.

+0

'void printFunc (const T & str)'를'void printFunc (const T str)'로 대체하면 ideone에서 오류가 사라집니다. 설명이 뭐야? http://ideone.com/ohoBZ – nims

+0

@nims : 편집을 참조하십시오. – AnT

+0

명확한 설명에 감사드립니다. 이제는 관련이 있습니다. – Smg