2017-06-01 2 views
-3

Ich schreibe eine abstrakte Klasse foo und bar Klasse erbt von foo.Was ist der Unterschied zwischen map <string, pair <string, foo * >> und map <string, pair <string, foo & >>?

Ich möchte einen Kartencontainer erstellen, der map<string, pair<string, foo&>> ist, aber ich kann nicht erfolgreich kompilieren. Der Compiler sagt mir

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

Hier Code:

#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(); 
} 

ich den Unterschied zwischen map<string, pair<string, foo*>> und map<string, pair<string, foo&>> wissen wollen.

+5

Wissen Sie, was der Unterschied zwischen einem Zeiger und einer Referenz ist? – NathanOliver

+2

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

+0

@ FrançoisAndrieux könnten Sie den Grund ausführlich erklären? – lens

Antwort

1

Das Problem mit dem ersten Beispiel (das Sie mit "falsch" beschriftet haben) ist die Zeile t[" t"] = p;. Wenn Sie std::map::operator[] in der Dokumentation anschauen, werden Sie die folgende Passage finden:

  • value_type muss EmplaceConstructible sein von std :: piecewise_construct, std :: forward_as_tuple (key), std :: tuple <>().

Dies bedeutet, dass Ihr mapped_type (in diesem Fall foo&) default konstruierbar sein muss. Verweise müssen jedoch immer auf ein vorhandenes Objekt verweisen, sie können nicht standardmäßig erstellt werden. Das Beispiel, das Zeiger verwendet, ist in Ordnung, da Zeiger diese Einschränkung nicht haben.

Sie können Referenzen wie die mapped_type verwenden, aber Sie müssen operator[] vermeiden. Zum Beispiel können Sie ein Element mit std::map::find finden oder eins mit std::map::emplace einfügen. Das folgende Beispiel kompiliert gut:

#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); 
} 
Verwandte Themen