2016-12-14 2 views
2

auto C++ 11 이상 유형을 어떻게 해석하는지 오해해야합니다. int (int a = ir/L;이) 잘 컴파일로 auto 교체, 그러나C + + 11 int & and long에서 산술 연산에서 자동 유형 공제

test.cpp: In function 'int main()': 

test.cpp:12:10: error: invalid initialization of non-const reference 
of type ‘int&’ from an rvalue of type ‘int’ 
    foo(a); 
     ^

test.cpp:1:6: note: initializing argument 1 of ‘void foo(int&)’ 
void foo(int& x) 
     ^~~ 

foo() 호출하기 전에 예상 된 결과 (a == 0을 제공합니다

void foo(int& x) 
{ 
    ++x; 
} 

int main() 
{ 
    int i = 2; 
    int& ir = i; 
    long L = 5; 
    auto a = ir/L; 
    foo(a); 

    return 0; 
} 

이 컴파일러 오류가 발생합니다 : 나는 다음과 같은 코드가 있습니다 , 및 이후 a == 1). 코드를 둘러보고 다양한 오류 메시지를보고 난 후에는 autolong int&으로 추론됩니다. void bar(int x)void bar(const int& x) 함수를 정의하면 call of overloaded ‘bar(long int&)’ is ambiguous이라는 오류 메시지가 나타납니다. 댓글에서

보정 :

이해가 어떻게 const가 아닌 심판에 의해 전달 될 수 좌변에서 auto x = [int&]/[int] 결과 동안에는 반지를 rvalue에 auto x = [int&]/[long] 결과가 없습니다.

+4

'a'는 참조가 아니며 간단한 'long'입니다. – LogicStuff

+3

^^^^^^ [이젠 길다] (http://ideone.com/lGpcWt) – StoryTeller

+2

이유가 오래 걸리는 이유를 모르면 유형 판촉이 그 원인입니다. 그리고 당신은 [이것에 대한 답을 읽어야합니다] (http://stackoverflow.com/questions/6770258/how-do-promotion-rules-work-when-the-signness-on-either-side-of-a-binary -opera) – StoryTeller

답변

4

ir/L의 결과는 long입니다. arithmetic operator의 경우 2 진수 연산자가 다른 유형 인 경우 생성되는 결과는 공통 ​​유형입니다. intlong 사이 일 경우 long이됩니다.

so auto a = ir/L;이므로 a의 유형은 long입니다. lvalue 참조를 다른 유형의 비 const로 바인딩 할 수 없으므로 foo(int&)으로 전달할 수 없습니다. L의 종류 주어진 한편

auto a = ir/L;를 들어, a의 유형은 int는 것, 그 다음 모든 것이 괜찮습니다, int이다. 당신이 long foo(int&)에, 먼저 컴파일러는 임시 방법 (일반를 rvalue)인지, int로 변환을 시도하고 결합 할 수없는 통과 "오류의를 rvalue 부분"에 대해

, lvalue 비 const 로의 참조.

long 암시 적 int로 변환 할 수 있으며, 일시적으로는 너무 bar(int x)bar(const int&) 잘 모두에 long 변수를 전달 CONST에 대한 참조를 좌변에 바인딩 할 수있다.

진술 : int a = ir/L;을 쓸 때 long 형식의 결과는 암시 적으로 int으로 변환됩니다. 따라서 int이 표시되면 foo(int&)으로 전달하면됩니다.

+0

나는 본다. 형식 변환을 임시 값 (오류 메시지의 rvalue)을 만드는 것으로 간주하지 않았습니다. 이것은 완벽하게 이해할 수 있습니다. 감사. –

1

auto을 사용한 사실은 관련이 없습니다.

a은 인수 승격의 규칙으로 인해 long 유형입니다.foo을 참조하여 파라미터소요

때문에 int&long 형 (그들은 같은 크기와 같은 보수 표현이 있더라도)에 결합 할 수 없으므로, 편집은 실패한다.

+0

'int const &'는 임시로 좁혀진'int'에 아주 잘 묶을 것입니다. – StoryTeller

+0

@StoryTeller : 당연하지! – Bathsheba