2016-06-17 14 views
3
#include <iostream> 
#include <string> 
#include <memory> 
#include <cstdlib> 

std::string foo() 
{ 
    return std::string("yyyyyyyyyyyyy"); 
} 

void bar(std::string& s) 
{ 
    std::cout << s << std::endl; 
} 


std::auto_ptr<std::string> foo1() 
{ 
    bool x = std::rand() % 2; 
    if (x) { 
     return std::auto_ptr<std::string>(new std::string("eeeeeeeeeeee")); 
    } else { 
     return std::auto_ptr<std::string>(new std::string("aaaaaaaaaaaaa")); 
    } 
} 


int main() 
{ 
    //bar(foo()); 
    std::auto_ptr<std::string> a(foo1());  
} 

bar가 비 const 참조를 허용하고 foo이 rvalue를 반환하기 때문에 주석 처리 된 행 : bar(foo())이 컴파일되지 않습니다. 그러나 std::auto_ptr의 두 번째 줄이 컴파일됩니다. std::auto_ptr의 복사 생성자는 비 const 참조도 허용합니다. 왜 컴파일됩니까? 나는 foo1std::rand()을 사용하여 RVO (반환 값 최적화)를 제거했습니다.std :: auto_ptr은 rvalue로 어떻게 초기화됩니까?

+4

[FYI] '표준 : auto_ptr'이 중단된다. 그것은'std :: unique_ptr'와'std :: shared_ptr'로 대체되었습니다. – NathanOliver

+0

알다시피 그래도 오래된 컴파일러를 사용해야합니다. – Ashot

+1

그런 다음 C++ 98 또는 C++ 03을 지정할 수 있습니다. C++ 자체에는 현재 표준 인 C++ 14가 포함되어 있습니다. – NathanOliver

답변

2

이것은 외관상으로는 내부 포인터를 std::auto_ptr에 놓기 위해 사용 된 약간의 트릭으로 인해 작동합니다. 케이스 This Manual 4 :

template< class Y > 
auto_ptr(auto_ptr_ref<Y> m); 

4)는 m에 의해 참조 auto_ptr은 인스턴스에 유지 auto_ptr은 포인터로를 구축. p.release()는 객체의 소유권을 획득하기 위해 보유하고있는 auto_ptr p에 대해 호출됩니다. auto_ptr_ref는 auto_ptr에 대한 참조를 보유하는 구현 정의 유형입니다. std :: auto_ptr은 암시 적으로이 유형으로 변환 가능합니다. 구현시 템플리트에 다른 이름을 제공하거나 다른 방식으로 동등한 기능을 구현할 수 있습니다.

(강조 추가)