-3

I write a abstract class foo, and bar class inherits from foo.

I want create a map container that is map<string, pair<string, foo&>>, but I cannot compile successfully. The compiler tells me

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

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

I want to know the difference between map<string, pair<string, foo*>> and map<string, pair<string, foo&>>.

anatolyg
  • 26,506
  • 9
  • 60
  • 134
lens
  • 133
  • 1
  • 11

1 Answers1

1

The problem with the first example (which you labeled "wrong") is the line t[" t"] = p;. If you look at the documentation for std::map::operator[] you will find the following passage :

  • value_type must be EmplaceConstructible from std::piecewise_construct, std::forward_as_tuple(key), std::tuple<>().

This implies that your mapped_type (in this case, foo&) must be default constructible. However, references must always refer to an existing object, they can't be default constructed. The example that uses pointers is fine because pointers don't have that restriction.

You can use references as the mapped_type but you will have to avoid operator[]. For example, you can find an element with std::map::find or insert one with std::map::emplace. The following example compiles fine :

#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);
}
François Andrieux
  • 28,148
  • 6
  • 56
  • 87