我编写了一个抽象类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&>>
之间的区别。
答案 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);
}