2016-06-17 8 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(foo())バーは非const参照を受け入れ、fooはrvalueを返すため、コンパイルされません。しかし、std::auto_ptrの2行目がコンパイルされます。 std::auto_ptrのコピーコンストラクタも非const参照を受け入れます。なぜそれがコンパイルされますか?私はfoo1std::rand()を使ってRVO(戻り値の最適化)を排除しました。std :: auto_ptrはrvalueでどのように初期化されますか?

+4

[FYI] 'のstd :: 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は暗黙的にこの型に変換可能であり、この型から割り当てることができます。実装では、テンプレートに別の名前を付けたり、同等の機能を他の方法で実装したりすることができます。

(強調追加)

関連する問題