map <string,pair <string,=“”foo * =“”>&gt;之间有什么区别?并映射<string,pair <string,=“”foo&=“”>&gt;?

时间:2017-06-01 15:33:00

标签: c++ reference stl c++-standard-library

我编写了一个抽象类foo,而bar类继承自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&>>之间的区别。

1 个答案:

答案 0 :(得分:1)

第一个示例(您标记为“错误”)的问题是行t[" t"] = p;。如果你查看std::map::operator[]的文档,你会发现以下段落:

  
      
  • value_type必须是来自std :: piecewise_construct,std :: forward_as_tuple(key),std :: tuple&lt;&gt;()的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);
}