잘못된 형식 :
int &z = 12;
올바른 형식 :
int y;
int &r = y;
질문 :
첫 번째 코드가 잘못된 이유는 무엇입니까? 제목에있는 오류의 " 의미 "는 무엇입니까?
잘못된 형식 :
int &z = 12;
올바른 형식 :
int y;
int &r = y;
질문 :
첫 번째 코드가 잘못된 이유는 무엇입니까? 제목에있는 오류의 " 의미 "는 무엇입니까?
(ostringstream() << "x=" << x).str()
답변:
C ++ 03 3.10 / 1은 "모든 표현식은 lvalue 또는 rvalue입니다."라고 말합니다. lvalueness 대 rvalueness는 객체가 아니라 표현식의 속성이라는 것을 기억하는 것이 중요합니다.
Lvalues는 단일 식 이상으로 지속되는 개체의 이름을 지정합니다. 예를 들어, obj
, *ptr
, ptr[index]
, 및 ++x
모든 lvalues입니다.
Rvalue는 그들이 살고있는 전체 표현의 끝에서 증발하는 임시입니다 ( "세미콜론에서"). 예를 들어, 1729
, x + y
, std::string("meow")
, 및 x++
모든 우변입니다.
연산자의 주소는 "피연산자가 lvalue이어야 함"을 요구합니다. 한 표현식의 주소를 취할 수 있다면 표현식은 lvalue이고 그렇지 않으면 rvalue입니다.
&obj; // valid
&12; //invalid
int & = 12;
이 유효하지 않은 이유에 답하기 위해 표준은 문자열 리터럴은 lvalue이고 다른 리터럴은 rvalue라고 말합니다.
std::string("meow")
유형의 객체를 std::string
생성하고이 객체를 지정하는 rvalue를 생성하고 1729
부작용이 없으며 값을 생성합니다. 유형의 rvalue로 1729 int
.
"Lvalues name objects that persist beyond a single expression."
은 100 % 정확한 진술입니다. 반대로, (const int &)1
"명명 된"객체가 아니기 때문에 귀하의 예제 는 올바르지 않습니다.
int &z = 12;
오른쪽 int
에는 정수 리터럴에서 임시 개체 유형 이 만들어 12
지지만 임시 개체는 상수 가 아닌 참조에 바인딩 될 수 없습니다. 따라서 오류입니다. 다음과 같습니다.
int &z = int(12); //still same error
임시가 생성되는 이유는 무엇입니까? 참조는 메모리에있는 객체를 참조해야하고 객체가 존재하려면 먼저 생성되어야합니다. 개체의 이름이 지정되지 않았기 때문에 임시 개체입니다. 이름이 없습니다. 이 설명에서 두 번째 경우가 좋은 이유가 꽤 분명해졌습니다.
임시 객체는 const 참조에 바인딩 될 수 있습니다. 즉, 다음과 같이 할 수 있습니다.
const int &z = 12; //ok
완전성을 위해 C ++ 11에 임시 개체에 바인딩 할 수있는 rvalue-reference가 도입되었음을 추가하고 싶습니다. 따라서 C ++ 11에서는 다음과 같이 작성할 수 있습니다.
int && z = 12; //C+11 only
의 &&
intead가 &
있습니다. 또한 바인딩 const
하는 객체가 z
integer -literal에서 생성 된 임시 객체 인 경우에도 더 이상 필요하지 않습니다 12
.
C ++ 11 도입 이후 r- 수치 참조 , int&
지금부터는라고 좌변 참조 .
12
에서 참조하는 데이터와 달리 변경할 수없는 컴파일 타임 상수입니다 int&
. 당신이 할 수 있는 것은
const int& z = 12;
void f( vector<int> const & )
수정되지 않는 벡터를 전달하는 관용적 함수를 고려하십시오 . 이제 문제는 그것이 f( vector<int>(5) )
올바르지 않으며 사용자 void f( vector<int> v ) { f(v); }
가 사소한 다른 과부하를 제공해야한다는 것입니다.
f( vector<int>(5) )
에서 컴파일러는 임시를 만든 다음 해당 임시에 대한 참조를 바인딩하고 유사하게 5
직접 암시 적 변환이있는 경우 . 이를 통해 컴파일러는 함수에 대한 단일 서명을 생성하고 단일 사용자가 함수를 구현할 수 있습니다. 이후부터는 일관성을 위해 나머지 상수 참조 사용에 대해 유사한 동작이 정의됩니다.
T const & r = *ptr;
의 이후 사용 r
하는 기능에 의해 대체 될 수 *ptr
및 r
런타임에 존재 할 필요가 없습니다) 또는 별칭이 지정된 객체의 주소를 유지하여 구현해야 할 수도 있습니다 (참조를 객체의 구성원으로 저장하는 것을 고려). 이는 자동 역 참조 된 포인터로 구현됩니다.
다음은 C ++ 언어의 규칙입니다.
12
) 로 구성된 표현식 은 "rvalue"입니다.int &ri = 12;
이 잘못되었습니다.이것이 C ++ 규칙이라는 것을 이해해야합니다. 그들은 단지 그렇습니다.
약간 다른 규칙을 사용하여 다른 언어, 예를 들어 C ++ '를 만드는 것은 쉽습니다. C ++ '에서는 rvalue를 사용하여 상수가 아닌 참조를 만들 수 있습니다. 여기에는 일관성이 없거나 불가능한 것이 없습니다.
그러나 그것은 프로그래머가 의도 한 것을 얻지 못할 수도있는 위험한 코드를 허용 할 것이고, C ++ 디자이너는 그 위험을 피하기로 올바르게 결정했습니다.
참조는 변경할 수있는 항목 (lvalue)에 대한 "숨겨진 포인터"(null이 아님)입니다. 상수로 정의 할 수 없습니다. "변수"여야합니다.
편집하다::
나는 생각하고있다
int &x = y;
거의 동등한
int* __px = &y;
#define x (*__px)
여기서 __px
새로운 이름이고, 상기는 #define x
단지 선언 함유 블록 내부 작동 x
참조.
const
:
const