일반적으로 gcc 4.7 및 C++ 11을 사용하는 현대의 컴파일러가 언제 그리고 왜 NVRO 최적화를 적용 할 수 없는지 알고 싶습니다.현대의 컴파일러는 어떤 경우에 함수에 NRVO 최적화를 적용 할 수 없습니까?
편집 :이 코드는 실수로 로컬 변수를 반환하지 않습니다. 나는 그런
A f(A&& v)
{
return v;
}
로했다 다른 질문에 대한 답변을 코드의 일부 조각을보고 그들이로 변경되었다 ideone.com/APySue
참조 아래에 더 좋은 예는 @ cooky451에 의해 공급 된
A f(A&& v)
{
return std::move(v);
}
그들은 lvalue v에 할당 된 통과 된 값이 여전히 rvalue이고 이동 될 수 있다고 말했기 때문에. 그러나 다른 이들은 NVRO에 대한 능력을 제거 할 것이라고 썼다. 이게 뭐야? 컴파일러가 임시가 반환된다는 것을 알고 있다면 아무 것도 움직이지 않고 직접 생성 할 수 있습니까? 나는 왜 사건 하나가 NVRO를 가지지 만 사건 2가 아니라는 것을 이해하지 못한다고 생각한다. 나는 사실을 잘못해서 질문 할 수있다. 또한, 나는 그 사건 2가 이런 이유로 안티 패턴이었고 당신이 std :: move를 돌려 보내면 안된다는 것을 읽었습니다. 추가적인 통찰력이 도움이 될 것입니다. 나는 뒤에서 컴파일러가 아래와 같이 만들 것이라고 들었다 : & __hidden__
은이 경우 myValue 함수에 할당된다.
A myValue = f(A());
// behind the scenes pseudo code for direct in place construction
void f(A&& v, A& __hidden__)
{
__hidden__ = v;
return;
}
나는이 예제를 간략하게 단순화했다고 생각합니다. 로컬 스택 변수가 반환되면 NVRO가 올바르게 발생 했어야합니까? – bjackfly
첫 번째 경우에만 https://ideone.com/APySue를 확인하십시오. 반환 값에 std :: move를 사용하는 것이 왜 반 패턴인지 이유 중 하나입니다. 다른 하나는 RVO를 수행 할 수없는 경우 복귀를 위해 자동으로 이동이 발생한다는 것입니다. ;-) 편집 : 때로는 반환 값에 대한 std :: move는 의미가 있지만이 경우는 드뭅니다. 레퍼런스, 특히 rvalue-reference로 작업 할 때 자신을 찾았습니다. – cooky451
NVRO가 첫 번째 경우에 적용될 수 있고 두 번째 경우에 적용될 수없는 이유는 내 주요 질문이라고 생각합니다. 좋은 예를 들어 더 잘 이해하기 위해 이걸 가지고 놀아 보겠습니다. – bjackfly