2017-02-28 18 views
3
#include <vector> 

using namespace std; 

void f(const vector<int>&) {} 
void f(vector<int>&&) {} 

int main() 
{ 
    { 
     vector<int> coll; 

     // 
     // coll is dying, so, 
     // "f(coll)" will call "f(const vector<int>&)" or 
     // "f(vector<int>&&)" as per C++11? 
     // 
     f(coll); 
    } 
} 

위의 코드에서 coll은 죽어 가고 있습니다. 따라서 f(coll)은 C++ 11에서 f(const vector<int>&) 또는 f(vector<int>&&)으로 전화 할 예정입니까?C++ 11은 죽어가는 객체가 인수로 복사되지 않고 이동된다는 것을 보장합니까?

+9

아니오; 이 경우'f (const std :: vector &')를 호출 할 것이다. 당신이 만들고있는 호출에서,'coll'은 명명 된 lvalue입니다. 'coll'이 다음 라인에서 범위를 벗어날 것이라는 사실은 부적합합니다. 만약 rvalue 버전의'foo'를 호출하고 싶다면,'f (std :: move (coll))'를 사용해야합니다. –

+0

당신은 무엇을 의미합니까? "콜이 죽어 가고 있습니다"_? 통화가 끝나면 파괴 될 것입니다. 당신은'foo (vector ())와 같은 것을 의미했을 것입니다. ' –

+1

'coll'은 중괄호 ({}')가 끝날 때까지 "죽어 가고"있지 않습니다. 중괄호 안에는 완벽하게 건강합니다 :-) 그러므로, 만약 당신이 rvalue를 얻길 원한다면 명시 적으로'std :: move (coll)'가 필요합니다 – AndyG

답변

5

f(coll)f(const vector<int>&) 대신 f(const vector<int>&)이 아니고 이는 잘못된 기능 과부하를 선택하기 때문에 표준을 위반하는 것입니다.

호가있는 위치와 호 이후에 coll을 사용하는 후속 진술이 있는지 여부에 따라 호의 해결 방법이 다른 경우 다소 혼란 스럽습니다.

특별한 치료 만 return values 주어집니다 :

expression는 좌변 표현과 생략이 충족하거나 충족 될 사본에 대한 조건은 다음, 그 표현 이름을 제외하고, 함수 매개 변수 인 경우 반환 된 값의 초기화에 사용할 생성자를 선택하기위한 오버로드 확인이 두 번 수행됩니다. 첫 번째 표현식이 rvalue 표현식 인 것처럼 (따라서 이동 생성자 또는 const를 참조하는 복사 생성자를 선택할 수 있음) 적절한 변환이없는 경우 사용 가능하며 lvalue 표현식으로 두 번째로 과부하 해결이 수행됩니다 (따라서 경찰을 선택할 수 있습니다 y 생성자가 비 const 로의 참조를 취함).

+5

이것에 덧붙이면 : * 허용하지 않는 것에 대한 매우 강력한 근거가 있습니다 컴파일러는이 경우에'foo'의 rvalue 버전을 호출합니다 ('coll'가 분명히 다음 줄의 범위를 벗어나더라도). 왜냐하면 이것이 허용된다면 누군가가 다음 줄에'coll'을 사용하는 문장을 추가한다면 프로그램의 행동이 바뀔 것이기 때문이다. 대부분의 사람들에게 혼란 스럽습니다. –