2016-07-06 3 views
1

マップ値にunique_ptrを使用しています。私はそれらの値を生ポインタのリスト/ベクトルとして取得する必要があります。これまで私は以下のようにしてきました。マップ値のunique_ptrから生ポインタを反復する

#include <iostream> 
#include <string> 
#include <vector> 
#include <memory> 
#include <map> 

class Foo { 
    public: 
    std::string val; 

    Foo(std::string v) : val(v) { 
    } 
}; 

class Unique { 
    public: 
    std::map<int, std::unique_ptr<Foo>> unique_map; 

    std::vector<Foo*> getFoos() { 
     std::vector<Foo*> foos; 
     for (auto& it : unique_map) { 
     foos.push_back(it.second.get()); 
     } 

     return foos; 
    } 
}; 

int main() { 
    Unique unique; 
    Foo* f1 = new Foo("1"); 
    Foo* f2 = new Foo("2"); 

    unique.unique_map.emplace(1, f1); 
    unique.unique_map.emplace(2, f2); 

    std::vector<Foo*> foos = unique.getFoos(); 

    for (Foo* foo : foos) { 
    std::cout << foo->val; 
    } 

    std::cout<<"\n"; 

    return 0; 
} 

しかし、これはコンパイルに失敗します。注意:前方:: 「STD((* & __args番号を変換することはできません最もreleventエラーメッセージが

「/usr/include/c++/4.8/bits/stl_tree.h:140:49のようです1)) '(タイプ 'はFoo * constの のstd :: & unique_ptrを「」

')を入力し' しかし、私は私の理解は、そのit.second戻っているので、私はそれが何を意味するのか理解してわかりませんunique_ptrへの参照ではなく、Fooインスタンスではなく、問題がどこにあるかを自分自身で仮定します。この例を修正するために何をする必要がありますか?

私は若干古いg ++バージョンを使用しています。コマンドラインで

グラム++(Ubuntuの〜14.04.3 4.8.4-2ubuntu1)4.8.4

グラム++ -std = C++ 11 -oユニークunique.cpp

+0

私のためにコンパイルしてください。 'g ++(GCC)6.1.1 20160602'、余分なフラグはありません。興味深い。 – Thomas

+0

だから、コンパイラのバグかもしれない?コンパイラの詳細を追加しました。 – chamibuddhika

+0

Clang ++もそれを受け入れます( '-std = C++ 11'が与えられたとき)。 'clang version 3.8.0(tags/RELEASE_380/final'。 – Thomas

答えて

1

エラーは、Foo*からstd::unique_ptr<Foo>への暗黙的な変換が許可されていないためです。これは、生ポインタを取るunique_ptrのコンストラクタがexplicitとマークされているためです。 emplace

NOTEをしながら

explicit 
     unique_ptr(pointer __p) noexcept 
     : _M_t(__p, deleter_type()) 
     { static_assert(!is_pointer<deleter_type>::value, 
        "constructed with null function pointer deleter"); } 

だから、あなたはunique_ptrmove、それを作成する必要があります:私はわからない、なぜか、どのようにG ++> 6.0ライブラリでの作業。しかし、個人的には、生のポインタを暗黙的にスマートポインタに変換することは安全だとは思わない。理由を知るには、https://stackoverflow.com/a/11367997/434233

+0

説明とリンクをありがとう。今より意味をなさない。私はあなたがこの動作の理由を説明したので、より良い答えとしてそれを受け入れるつもりです。 – chamibuddhika

+0

@Arunmuこの暗黙的な変換は危険ですが、Sutterの記事をリンクすると、他の方向(生まれつきから生き生きとしたものからスマートなものまで)で話すことにつながります。 – Thomas

+0

@Thomasええ、ありがとう。関連する回答を指すようにリンクを更新しました – Arunmu

1

私はこのコードを実行すると、苦情がstd::pairクラスの作成に関連しているようです。

unique.unique_map.emplace(1, std::unique_ptr<Foo>(f1)); 
unique.unique_map.emplace(2, std::unique_ptr<Foo>(f2)); 

私にとっては、これは構築されていますが、実際にはあなたが望むことを行うとは確信できません。ちょうどコンパイルされ、私のために実行されます。

QTライブラリとクラスを使用してC++の時間をほとんど費やしていますが、FOO*のペアをunique_ptr<FOO>に変更する方法が見つからないようです。

+0

確かに!明示的なstd :: pairベースの挿入を使用したとき、それは機能しました。私が思っていたようにemplaceが動作しないように見えます(少なくとも私の現在のコンパイラでは見えます)。 – chamibuddhika

関連する問題