以下是我的问题的大致代码。首先,我们有一个带构造函数的结构:
struct Pair{
Pair(int a, int b): (first (a) , second (b) ) {}
int first;
int second;
};
用于地图
map<string, Pair> mymap;
我想在函数中初始化这个地图
void f(map<string, Pair>* mymap, string c,int x, int y )
{
(*mymap)[c]=Pair(x,y);
}
但编译器首先说它找不到合适的构造函数然后接下来的行就是没有为构造函数提供足够的参数。
我的一个朋友告诉我,我应该写这样的功能:
void f(map<string, Pair>& mymap, const string& c,int x, int y )
{
if (mymap.find(c) != mymap.end()) {
mymap[c] = Pair(x,y);
}
}
但是他无法解释为什么 Type&amp; 应该在这里使用而不是 Type *,我想澄清这一点。有人可以解释一下吗?
答案 0 :(得分:3)
问题是地图中的operator[]
要求值类型是默认可构造的。如果您不希望Pair
成为默认构造,则必须避免使用operator[]
:
void f(map<string, Pair>& mymap, string c,int x, int y )
{
mymap.insert( std::make_pair(c,Pair(x,y)) );
}
你可能误解了你朋友的建议。 operator[]
的问题不在于它需要默认构造函数如果需要创建一个新元素,但它需要它以防它可能需要 。也就是说,元素是否存在之前并不重要。
如果您还想更新,那么您还需要考虑该选项:
void f(map<string, Pair>& mymap, string c,int x, int y )
{
auto res = mymap.insert( std::make_pair(c,Pair(x,y)) );
if ( !res.second )
res.first->second = Pair(x,y);
}
基本上insert
操作返回一对指向键的迭代器和一个bool,指示这个insert
是否创建了对象,或者它是否已经存在(在这种情况下是地图中的值)是未经修改的)。通过存储结果,我们可以测试,如果insert
没有创建值,我们可以通过返回的迭代器更新它。
答案 1 :(得分:2)
在地图上调用operator[]
将要求您的类型是默认可构造的。您可以使用map::insert或map::emplace
答案 2 :(得分:2)
您需要一个默认的控制器:
Pair(): first () , second () {}
这是地图的operator[]
所必需的,它会创建默认构造的mapped_type
使用不存在的密钥调用时 -
和一个实现strict weak ordering的小于运算符:
struct Pair {
// as before
bool operator<(const Pair& rhs) const {
/ some code to implement less-than
}
};
或者您可以将比较函子或函数实现严格弱序排列作为
第三个模板参数。 击>
答案 3 :(得分:0)
标准容器需要默认构造函数。他们将使用operator=
在构建后的某个时刻设置正确的值。