2017-01-02 1 views
7

내가 이해 한 바로는 C++은 왼쪽에서 오른쪽으로 작동합니다. 내가 예를 들어, :"="연산자는 무엇을 반환합니까?

std::cout << "output" << "stream"; 

C를 권리 ("출력")에서 리터럴 문자열을 받아 넣어 < < 운영자가 옆 ++ 첫째, 가장 왼쪽에있는 것은 (표준 : COUT)에서 시작 그것을 연산자의 왼쪽에있는 객체 (std :: cout)에 넘깁니다. 그런 다음 C++은 연산자 (std :: cout)의 왼쪽에있는 객체를 반환 한 다음 다른 코드 < <을 계속합니다.

"="연산자는 무엇을 반환합니까?

double wage = 5; 
double salary = wage = 9999.99; 

나는 "="연산자가 "="의 왼쪽 또는 오른쪽 피연산자를 반환 생각 나는 경우. 그래서, 내 논리와 함께, 급여 초기화 라인에서 급여는 임금의 값으로 초기화되고, "="연산자는 급여 또는 임금 (급여라고합시다)을 반환 한 다음 급여에 9999.99를 할당하지만 임금은 그 값은 5가 유지되어야합니다.

그러나 "급여"초기화 후 "급여"및 "임금"값을 확인할 때 값은 모두 9999.99입니다. 위의 std :: cout과 동일한 논리를 적용하면 "salary"또는 "wage"중 값이 9999.99 인 하나의 변수 만 있어야합니다.

+6

* "C++은 왼쪽에서 오른쪽으로 작동합니다"* 운영자에 따라 다릅니다. '= '는 특히 우연히 연관되어 있습니다. 그것은 오른쪽에서 왼쪽으로 작동합니다. –

+7

@Igor :'double salary = wage = 9999.99;에 단 하나의 대입 연산자가 있습니다. 따라서 연관성은 중요하지 않습니다. –

답변

17

할당 연산자는 오른쪽에서 왼쪽으로 연관되어 있으며 일반적으로 왼쪽 피연산자를 참조로 반환합니다. 일반적으로 말하자면, 이것은 내가 생각할 수있는 모든 내장 유형, 라이브러리 유형에 해당합니다. 이것이 할당 연산자를 작성하는 방법입니다.

double salary = wage = 9999.99; 

여기에 두 번째 줄에, salarywage하지 9999.99로 설정됩니다 것을 정확히 같은

wage = 9999.99; 
double salary = wage; 

으로 참고 있다는 것을 의미

. 구별은 여기서 중요하지 않지만 어떤 경우에는 구별 될 수 있습니다. 예를 들어 (예를 들어 저스틴 시간 덕분에) : 명확 관계없이 9998.99의 값을 가져옵니다,하지만

double salary = --(wage = 9999.99); 

salary

wage뿐만 아니라 않는다는 점에 유의하는 것이 중요합니다; 할당이 올바른 인수를 대신 반환하면 wage은 임금 할당이 발생한 후에 임시 할당이 감소하기 때문에 9999.99가됩니다.

벤 보이트 (Ben Voigt)는 아래의 의견에서 지적했듯이 나의 대답은 정확하지만, 필자가 사용하는 질문의 예는 다소 오해의 소지가 있습니다. 문제의 코드에서 = 토큰이 두 번 나타나기는하지만 실제로는 double salary = wage = 9999.99은 할당을 두 번 호출하지 않고 할당을 호출 한 다음 새 이중을 생성하기 때문입니다.다음의 예는 더 계속 될 것입니다 :

double salary = 0.0; 
salary = wage = 9999.99; 

이제 우리는 진정으로 체인하는 대입 연산자와 우선 순위 및 반환에 대한 모든 내 이전 의견은 여기에 코드의 두 번째 라인에 적용 할 수 있습니다.

+1

['std :: atomic' 템플릿은 예외입니다.] (http://en.cppreference.com/w/cpp/atomic/atomic/operator%3D)''this'를 반환하는'operator ='규칙 참조로. –

+0

@BenVoigt 이것은 흥미로운 예입니다. 그러나이 연산자는 대입 연산자이지만 클래스의 복사 할당 연산자는 아닙니다. 오히려 이질적 할당입니다. 나는 진실한 copy assignment operators를 생각하고 있었지만, 그것은 텍스트에 포함되지 않았다. –

+0

BTW, 귀하의 대답은 연관성이 중요한 예제를 포함시킴으로써 향상 될 것입니다. 질문에있는 코드에는 할당 연산자의 사용법이 하나만 포함되어 있지만 '='토큰이 세 번 나타납니다. –

3

operator precedence table을 참조하십시오. 대입 연산자, =은 "오른쪽에서 왼쪽으로"결합 성입니다. wage = 9999.99 함께

double salary = (wage = 9999.99); 

먼저 발생 :도록 발현을 효과적으로 평가한다.

+3

이것은 연관성과는 아무런 관련이 없지만 초기화 문법의 문법과는 관련이 없습니다. –

+0

이것이 초기화가 아니라 변수가 이미 선언 된 변수에 대한 할당 문인 경우. 'x = 1; x = y = z; '그러면 연관성이 관련성이 있습니까? – selbie

+0

물론 가능합니다. –

1

표현식은 값이이고 부작용이 있습니다.입니다. 값 (당신이 "return"이라고 부르는 것)은이 표현식이 피연산자 인 다른 연산자에 사용될 것입니다. (그러한 연산자가없는 경우에도 여전히 계산됩니다.) 표현식의 값을 찾는 프로세스는 값 계산이라고합니다.

값은 value category 일 수 있습니다. 부작용은 메모리 위치를 업데이트하거나 함수를 호출하는 것과 같이 발생합니다.

일반적으로 더 큰 하위 표현식에서 값을 사용하기 전에 부작용이 발생할 수도 있고 발생하지 않을 수도 있습니다. 유명하게도 postfix-++ 연산자는 값과 부작용 사이의 타이밍에 큰 차이가있을 수 있습니다.

할당 표현식의 경우 값은 왼쪽 피연산자 (값 카테고리 "lvalue")이며 부작용은 왼쪽 피연산자로 지정된 객체가 오른쪽 피연산자의 값을 포함하도록 업데이트된다는 것입니다. 부작용은 값 계산 이전에 순으로 정렬되어 더 큰 표현식이 값을 사용하면 이미 새 값이 저장된 메모리 위치가 지정됩니다. 코드가 있다면

:

salary = wage = 9999.0; 

는 운영자 연관성 규칙은 salary = (wage = 9999.0); 것을 의미 할 것입니다. 내부 표현식은 값 카테고리 lvalue을 갖는 값 wage을 가지며 내부 표현식의 부작용은 wage이라는 변수가 9999.0을 저장하고 할당 연산자의 순서 지정을 통해 결과가 이미 저장되어 있음을 보증합니다 그 다음 가장 바깥 쪽의 표현. 그 다음은 실제 코드는 선언입니다 salary = wage;


참고하고, 선언의 첫 번째 = 기호에 해당 즉 우리가 X는 이전 단락에 기술 된 값입니다 salary = X을 가지고

할당 연산자가 아닙니다. 대신 이니셜 라이저가 오는 문법적 마커입니다. 코드는 동일하다 :

double salary { wage = 9999.0 }; 
1

귀하의 예를

double wage = 5; 
double salary = wage = 9999.99; 

중 & hellip에서; 즉

wage = 9999.99 

=의 다른 인스턴스가 초기화 구문의 일부 하나의 과제이있다.

할당은 할당 된 객체에 대한 참조 (이 경우 wage)를 반환합니다.그래서 예,

double wage; 
double salary; 
wage = 5; 
salary = wage = 9999.99; 

중 & hellip

double wage = 5; 
wage = 9999.99; 
double salary = wage; 
귀하의 예제는 여러 과제를 사용하여 다시 작성하는 경우

에 해당; 할당 연산자가 올바른 연관성을 갖는 것이 중요해진다. 따라서 마지막 줄은

salary = (wage = 9999.99); 

& hellip과 동일합니다. 여기서 괄호로 둘러싸인 표현식은 wage에 대한 참조를 반환합니다.


표준 컨테이너를 사용하려면 사용자 정의 할당 연산자가 할당 된 객체에 대한 참조를 반환해야합니다. 핵심 언어에는 그러한 요구 사항이 없기 때문에 void을 사용하려고 할 수 있습니다. 나는. 좋은 모두 신성 부작용 기반 코드,보다 간결한 구현 지원하지 효율성을 보장 : delete 또는 default 할당 오퍼레이터

struct S 
{ 
    void operator=(S); // OK with respect to core language rules. 
}; 

그러나 순서를 작업자의 선언 그것을 기준을 제공한다 반환형 : 제 & 파지 한편

struct T 
{ 
    auto operator=(T const&) -> T& // But `void` won't work here. 
     = delete; 
}; 

없이 보장 효율 및 용장 ungood지지를 위해 부작용 기반 코드 operator= 별도 void 부재로 표현 될 수있다 함수도 될 수 있습니다. 에일러론 :

struct U 
{ 
    void assign(U other); 

    auto operator=(U const& other) 
     -> U& 
    { 
     assign(other); 
     return *this; 
    } 
}; 
관련 문제