2013-12-14 5 views
11

컴파일러는 lvalue를 rvalue 레퍼런스에 바인드하려고하는데 불평을 계속합니다. 그러나 어떻게 볼 수는 없습니다. 나는 C++ 11, move semantics 등을 처음 사용하기 때문에 나와 함께 견뎌야한다. 이 메소드를 호출Lvalue에서 rvalue 로의 레퍼런스 바인딩

template <typename Key, typename Value, typename HashFunction, typename Equals> 
Value& FastHash<Key, Value, HashFunction, Equals>::operator[](Key&& key) 
{ 
    // Some code here... 

    Insert(key, Value()); // Compiler error here 

    // More code here. 
} 

:

template <typename Key, typename Value, typename HashFunction, typename Equals> 
void FastHash<Key, Value, HashFunction, Equals>::Insert(Key&& key, Value&& value) 
{ 
    // ... 
} 

나는 다음과 같이 점점 오류를 계속 : 삽입() 호출에

cannot convert argument 1 from 'std::string' to 'std::string &&' 

나는이 기능을 가지고있다. 연산자 오버로드에서 r 값으로 key이 정의되어 있지 않습니까? 왜 그것이 lvalue로 재 해석되고 있습니까?

감사합니다.

답변

18
Insert(key, Value()); // Compiler error here 

key 여기는 Key&& key입니다. 이것은 lvalue입니다. 그것은 이름을 가지고 있으며 당신은 그 주소를 취할 수 있습니다. 그 lvalue의 타입은 "Key의 rvalue reference"입니다.

당신은를 rvalue를 전달해야하고, 그것을 위해 당신은 std::move를 사용해야합니다 : 이것이 이해 왜 내가 볼 수

Insert(std::move(key), Value()); // No compiler error any more 

! 그러나 rvalue reference (rvalue에 바인딩 된 참조)와 실제 rvalue를 구별하면 더 명확 해집니다.

편집 : 실제 문제는 여기에 rvalue 참조를 사용하는 것입니다. 인수의 유형이 추론되는 함수 템플리트에서 인수를 사용하는 것이 좋습니다. 이는 인수가 참조 축소 규칙으로 인해 lvalue 참조 또는 rvalue 참조에 바인드되도록 허용하기 때.입니다. 왜이 문서와 비디오를 참조하십시오 http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers

그러나, 함수가 호출 될 때 FastHash<std::string, ... >를 인스턴스화 할 때 이미 클래스에 의해 결정 된대로 키의 유형이 도출되지 않는이 경우이다. 따라서 우변 값 참조를 실제로 처방하므로 std::move을 사용하면 코드가 수정됩니다.

나는 매개 변수 값으로 취할 것을에 코드를 변경합니다 :

template <typename Key, typename Value, typename HashFunction, typename Equals> 
Value& FastHash<Key, Value, HashFunction, Equals>::operator[](Key key) 
{ 
    // Some code here... 

    Insert(std::move(key), Value()); 

    // More code here. 
} 

template <typename Key, typename Value, typename HashFunction, typename Equals> 
void FastHash<Key, Value, HashFunction, Equals>::Insert(Key key, Value value) 
{ 
    // ... 
} 

값 인수의 사용으로 인해 추가 복사본에 대해 너무 많이 걱정하지 마세요 -이 자주 컴파일러에 의해 최적화되어 있습니다.

+2

lvalue의 유형이 "Key"가 아닌가요? rvalue-reference-ness는 어떤 방식으로 보존됩니까? – hvd

+0

이 작동하지만 hvd 제기 한 문제를 이해할 수 있는지 잘 모르겠습니다. 설명해 주시겠습니까? –

+0

@hvd 그녀가 진행하는 인수 유형 공제가 없기 때문에 보존됩니다. 제 편집을 참조하십시오. – polkadotcadaver