2017-06-01 25 views
-3

私は抽象クラスfooを書き、barクラスはfooから継承します。map <string、pair <string、foo * >>とmap <string、pair <string、foo&>>の違いは何ですか?

map<string, pair<string, foo&>>のマップコンテナを作成したいが、正常にコンパイルできない。コンパイラは、ここで私に

“std::pair<std::string,foo &>::pair”: not appropriate default constructor 

を伝えるコードです:

#include <iostream> 
#include <string> 
#include <windows.h> 
#include <map> 
#include <utility> 

using namespace std; 

class foo 
{ 
public: 
    virtual void t() = 0; 
}; 

class bar :public foo 
{ 
public: 
    void t() 
    { 
     cout << "bar" << endl; 
    } 
}; 

int main() 
{ 
    bar b; 
    //wrong 
    //map<string, pair<string, foo&>> t; 
    //pair<string, foo&> p("b", b); 
    //t["t"] = p; 

    //right 
    map<string, pair<string, foo*>> t; 
    pair<string, foo*> p("b", &b); 
    t["t"] = p; 
    p.second->t(); 
} 

私はmap<string, pair<string, foo*>>map<string, pair<string, foo&>>との違いを知りたいです。

+5

ポインタと参照の違いは何ですか? – NathanOliver

+2

https://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable-in –

+0

@FrançoisAndrieux理由を詳しく説明できますか? – lens

答えて

1

最初の例(「間違っている」というラベルが付けられています)の問題は、t[" t"] = p;という行です。あなたがstd::map::operator[]のドキュメントを見れば、あなたは次の一節があります:

  • VALUE_TYPEはSTD :: piecewise_construct、STD :: forward_as_tuple(キー)、STD ::タプル<>()からEmplaceConstructibleでなければなりません。

このはあなたmapped_type(この場合には、foo&)デフォルト構築可能でなければならないことを意味します。しかし、参照はでなければならず、常には既存のオブジェクトを参照する必要があります。デフォルトの構築はできません。ポインターにはその制限がないため、ポインターを使用する例は問題ありません。

参考資料はmapped_typeとして使用できますが、operator[]は避けてください。たとえば、std::map::findの要素を見つけたり、std::map::emplaceの要素を挿入したりできます。次の例では、コンパイルが正常に行われます。

#include <string> 
#include <map> 
#include <utility> 

using namespace std; 

struct foo {}; 

int main() 
{ 
    foo b; 
    //wrong 
    map<string, pair<string, foo&>> t; 
    pair<string, foo&> p("b", b); 
    t.emplace("t", p); 
} 
関連する問題