명백한 대답은 정확하고 기본적으로 최적입니다. 에서
void do_stufF(std::vector<int>& on_this); // (1)
std::vector<int> do_stuff_better() { // (2)
std::vector<int> myVector_temp; // (3)
do_stuff(myVector_temp); // (4)
return myVector_temp; // (5)
}
(3) 우리 (스택)에 자동 저장 명명 된 결과 값을 생성한다.
(5) 우리는 함수에서 이름 지정된 반환 값만 반환하며 함수의 다른 곳에서는 반환 값을 반환하지 않습니다. (3)과(5) 컴파일러가 myVector_temp
물체의 존재를 생략하다 (거의 확실하고)가 허용되기 때문에
. 함수의 반환 값을 직접 생성하고 은myVector_temp
이라고합니다. 기존의 이동 또는 복사 생성자가 필요하지만 여전히 호출하지 않습니다. do_stuff_better
를 호출 할 때
다른 쪽 끝에서
, 어떤 컴파일러는 호출에서 할당을 제거하다 할 수 있습니다
컴파일러 효과적으로 "밥 포인터의"를 전달하고 그것의 반환을 구성
do_stuff_better()
에게 허용
std::vector<int> bob = do_stuff_better(); // (6)
값을 bob
의 위치에 추가하여이 사본 구성을 제거하십시오. do_stuff_better()
이 반환 값을 생성하도록 요청 된 위치가 bob
의 위치와 같아 지도록 호출이 이루어지는 방식을 조정할 수 있습니다.
그리고 C++ 11에서는 두 엘레멘트에 대한 요구 사항이 모두 충족되지 않거나 컴파일러에서 사용하지 않기로 선택한 경우에도 copy
대신 move
을 사용해야합니다.
라인 (5) 우리는 지역적으로 선언 된 자동 저장 기간 변수를 평범하고 간단한 return
문으로 반환합니다. 이렇게하지 않으면 반환 값이 암시 적 move
이됩니다.
줄에서 (6)이 함수는 이름이없는 개체 인 rvalue를 반환합니다. bob
이 구성되면 move
- 구성됩니다.
move
ing a std::vector
은 ~ 3 포인터의 값을 복사 한 다음, vector
의 크기에 관계없이 원본을 제로로 구성합니다. 요소를 복사하거나 이동할 필요가 없습니다.
우리가 do_stuff_better()
내에서 명명 된 지역 변수를 제거하고 우리가 do_stuff_better()
의 return
값을 제거하고 대신 직접 bob
를 구성 위 elisions, 모두 다소 취약하다. 컴파일러가 그러한 엘레멘트를 할 수있는 규칙을 배우고, 컴파일러가 실제로 엘리트를 수행하는 상황을 배우는 것도 가치가 있습니다.
오류 상태를 확인한 후 do_stuff_better()
에 return std::vector<int>()
을 수행 한 지점이있는 경우 취약한 방법의 예로서 기능 중 일부가 차단되었을 수 있습니다.
elision이 차단되거나 컴파일러가 사례를 구현하지 않더라도 컨테이너가 move
'이라는 사실은 런타임 비용이 최소화된다는 것을 의미합니다.
그리고 왜 이것이 차선책이라고 생각합니까? – delnan
새로운 함수가 중간 벡터'벡터 '을 생성하지 않을까요? 그럼 선언에 복사 될까요? –
원본 버전보다 훨씬 뛰어난 버전입니다. 실적이 걱정된다면 [반환 값 최적화] (http://en.wikipedia.org/wiki/Return_value_optimization)를 읽어보십시오. – juanchopanza