2014-07-22 5 views
4

이 코드를 생각해 보자. 따라서이 메서드를 호출 할 때 복사가 필요하지 않습니다. 따라서 이동이 가능한 unique_ptr으로 이러한 함수를 호출하면됩니다. 그러나 컴파일되지 않습니다이 코드 :C++ 없습니다

test.cpp:24:34: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’ 
    std::unique_ptr<int> b = mov(a); 

가 그래서 C++에서 unique_ptr의 삭제 물론이다 생성자를 복사 호출을 시도하는 것 : 나는 오류가 발생합니다. 그런데 왜 여기에서 사본이 생깁니 까? 이 코드를 컴파일하려면 어떻게해야합니까?

+1

'표준 : B = MOV unique_ptr (표준 : : 이동 (a)는) 그건,'* * 일이 잘못되고있는 것이 무엇인지에 대한 힌트를해야합니다. – WhozCraig

+0

@WhozCraig : 나는 특히 여기에 '이동'을 피하고자합니다. 그렇지 않으면, 나는 범용 참조가 아니라 rvalue 참조가 필요합니다. 보편적 인 리펙스 **의 요점은 ** 평범한 lvalue reference를 보유 할 수 있다는 것입니다. – gexicide

+0

그럼 내가 마지막 경기를 보지 않을거야. 내 의견에 따라 움직이지 않고'mov' * 안에서 'a'라고 생각하는 것이 무엇입니까? 'T &&'는 [xvalue] (http://en.cppreference.com/w/cpp/language/value_category)로 승격되지 않았습니다. 그것은 움직여야 할 필요가있다. (또는 나는 그것을 처음 보지 않을 것이다.) – WhozCraig

답변

3

: remove_reference&&없이 사용하여 니얼가 언급 한 바와 같이

template<typename T> 
typename std::remove_reference<T>::type&& mov(T&& t){ 
    return std::move(t); 
} 

, 참조로 반환하는 것도 작동합니다 그리고 mov이 버전의 미세 컴파일하고 문제를 해결, 일 mov

의 반환 형식은 코드 읽어야합니다

#include <utility> 
#include <memory> 
template<typename T> 
typename std::remove_reference<T>::type&& mov(T&& t){ 
    return std::move(t); 
} 

int main(){ 
    std::unique_ptr<int> a = std::unique_ptr<int>(new int()); 
    auto b = mov(a); 
} 

반환 값 시나리오에서 힌트를 얻은 질문은 컴파일됩니다. 나는 그것이 당신의 상황에서 효과가 있을지 확신하지 못합니다.

template<typename T> 
typename std::remove_reference<T>::type mov(T&& t){ 
    return std::move(t); 
} 
+0

나는 당신 앞에서 똑같은 것을 알아 냈지만 어쨌든 대답을 주셔서 감사합니다. – gexicide

+0

해결책은 나에게 분명했습니다. 나에게 분명하지 않은 것은 왜 원본이 틀린 지에 대한 설명입니다. – Mehrdad

+0

@ 쥬 시지 사이드 이제 알겠습니다. 동기식 타이핑. 좋은 작은 문제는 생각했다. 나는 레퍼런스 붕괴가 사람들을 얼마 동안 얻게 될 것이라고 생각한다. 벌써 몇 번 물어 뜯어. – Niall

3

나는 마침내 작동하는 해결책을 발견했다. 나는 그 문제가 가치에 의한 반환이 사본을 유발할 것이라고 생각한다. 대신 나는 rvalue 참조에 의해 반환이 필요합니다; 그러면 자동으로 이동이 수행됩니다. 우선이 시도 :

template<typename T> 
T&& mov(T&& t){ 
    return std::move(t); 
} 

을하지만 지금 문제는 반환 형식 T&&보편적 참조 아닌를 rvalue 참조 것입니다. 따라서 lvalue 함수를 호출 할 때 실제 서명은 T& mov(T& t)입니다. 그 때문에, 좌변 참조에 std::move을 넣을 수 없기 때문에 본체가 컴파일되지 않습니다. 이 여기에, 무슨 일이 생긴 정확히이었다 오류입니다 :

test.cpp:18:22: error: invalid initialization of non-const reference of type 

‘std::unique_ptr<int>&’ from an rvalue of type ‘std::remove_reference<std::unique_ptr<int>&>::type {aka std::unique_ptr<int>}’ 
    return std::move(t); 

그래서, 내가 반환 유형으로 실제를 rvalue 참조를 필요로했다. 처음에는 그것을 어떻게 구성해야할지 모르지만 마침내 std::remove_reference 유형을 T으로 변경 한 다음 &&을 추가하면 실제 값은 T&&이됩니다. 내가 오류에 생각

template<typename T> 
typename std::remove_reference<T>::type mov(T&& t){ 
    return std::move(t); 
} 
+0

반환 유형을 'typename std :: remove_reference :: type'으로 만들까? – Mehrdad

+0

@Mehrdad : 네, 그렇습니다. 하지만 난 이유를 모르겠다 – gexicide

+0

@Mehrdad 귀하의 코멘트를 보았습니다. 타이핑을 동기화하십시오. 여기에 가치에 의한 반환은 원래의 질문에 암시되었습니다. – Niall