【问题标题】:initialize std::map value when its key does not exist当其键不存在时初始化 std::map 值
【发布时间】:2013-05-05 08:57:11
【问题描述】:

我在here 中读到,如果键不存在,std::map operator[] 会创建一个对象

首先我可以知道在哪里可以找到此声明的参考资料吗?(虽然我知道这是真的)

接下来,想象下面的代码 sn-p:

#include <iostream>
#include <vector>
#include<map>

class Value {
//..
    int some_member; //is used for any purpose that you like
    std::vector<int> some_container;
public:
    Value(int some_member_) :
            some_member(some_member_) {
        std::cout << "Hello from the one-argument constructor" << std::endl;
    }
    Value() {
        std::cout << "Hello from the no argument constructor" << std::endl;
    }
    void add(int v) {
        some_container.push_back(v);
    }
    int getContainerSize()
    {
        return some_container.size();
    }

//...
};

//and somewhere in the code:

class A {
public:
    std::map<int, Value> myMap;

    void some_other_add(int j, int k) {
        myMap[j].add(k);
    }
    int getsize(int j)
    {
        return myMap[j].getContainerSize();
    }

};
//and the program actually works
int main() {
    A a;
    std::cout << "Size of container in key 2 = " << a.getsize(2) << std::endl;
    a.some_other_add(2, 300);
    std::cout << "New Size of container in key 2 = " << a.getsize(2) << std::endl;

    return 1;
}

输出:

Hello from the no argument constructor
Size of container in key 2 = 0
New Size of container in key 2 = 1

我可以从上面的输出中看到调用了无参数构造函数。

我的问题是:有没有办法调用 map 的 Value(s) 的单参数构造函数?

谢谢

【问题讨论】:

标签: c++ constructor stdmap


【解决方案1】:

我可以知道在哪里可以找到此声明的参考资料吗?

这是 C++11 标准的要求。根据第 23.4.4.3 段:

T& operator[](const key_type& x);

1 效果:如果映射中没有与x 等效的键,则将value_type(x, T()) 插入映射中。

[...]

T& operator[](key_type&& x);

5 效果:如果地图中没有与x等效的键,则将value_type(std::move(x), T())插入 地图。

关于第二个问题:

有没有办法调用map的Value(s)的单参数构造函数?

你可以在 C++03 中做到这一点:

void some_other_add(int j, int k) {
    myMap.insert(std::make_pair(j, Value(k)));
}

并在 C++11 中使用emplace() 成员函数:

myMap.emplace(j, k);

【讨论】:

  • 安迪,谢谢你的回答。我想 C++03 的唯一解决方案就是你刚才提到的那个。
【解决方案2】:

您可以在 cppreference.com 找到对 std::map&lt;…&gt;::operator[] 的有用描述。

我假设您希望有条件地使用非默认构造函数添加一个值,即,当相应的键不存在于地图中时。

C++03

std::map<int, Value>::iterator i = myMap.find(j);
if (i == myMap.end())
    i = myMap.insert(std::map<int, Value>::value_type(j, 123)).first;
i->add(k);

C++11

auto i = myMap.find(j);
if (i == myMap.end())
    i = myMap.emplace(j, 123).first;
i->add(k);

在这两种情况下,新插入的Values 将有 some_member == 123。

【讨论】:

  • Marcelo +1 供参考。解决方案也是正确的。非常感谢
  • 你不需要 find(),emplace() 已经在 std::map 中做到了。您的代码还会出现编译器错误,因为 emplace 返回一对 这与 find() 返回的不同
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-27
  • 1970-01-01
  • 2021-02-12
  • 2017-05-31
相关资源
最近更新 更多