繁体   English   中英

C ++ map inversion初始化

[英]C++ map inversion initialize

当我读一些文章时,我看到了一些奇怪的东西(对我而言)。

当我使用地图时,我会像这样使用它:

std::map<std::string, MyClass> Map;
//and add elements:
Map['someting'] = myObject;

这很好,也很容易理解。 但是在这篇文章中我看到了这个:

MyClass& object = Map['something_new'];
//and then, initialize the object
object.method();
//and later I can use this map
Map['something_new'];

并且...它的工作原理。 但我不明白怎么做。 我初始化一个对象引用,而不是map,但这就像我刚刚在我的地图中添加了一个元素。 有人可以向我解释一下吗?

正如std::mapoperator[]文档所说:

返回对映射到等效于key的键的值的引用 ,如果此类键尚不存在则执行插入

换句话说, std::map的设计是这样的,你总是通过operator[]获得对现有有效元素的引用,无论是在调用之前存在还是在运行中创建的元素。

当然,其他设计也是可能的。 例如,如果密钥不存在,或者行为可能未定义,则可能抛出异常。 但是自动元素创建是std::map最终的结果。

如果您不希望自动插入元素,则不应使用operator[] 您可以使用以下代码:

auto const find_iter = Map.find("something_new");
if (find_iter != Map.end())
{
    MyClass& object = *find_iter;
    // ...
}
else
{
    // do whatever you want when there is no "something_new" element
    // ...
}

如果访问不存在的键, std::map将使用默认构造函数自动创建新对象。

看这个例子:

#include <string>
#include <iostream>
#include <map>

class Demo {
public:
    Demo() { std::cout << "ctor" << std::endl; }
};

int main(int argc, const char * argv[]) {

    std::map<std::string, Demo> m;
    std::cout << "Access unknown element." << std::endl;
    m["a"];
    m["b"];
    m["c"];
}

输出是:

Access unknown element.
ctor
ctor
ctor

访问的每个不存在的元素都是使用默认构造函数自动构造的。 这也适用于像int这样的简单数据类型。

operator[] (element_access)不是const函数; 如果键的值尚不存在,它实际上会在地图中插入一个新元素。

map['non_existing_key']实际上会增加容器的size()

如果k与容器中任何元素的键不匹配,则该函数将使用该键插入一个新元素,并返回对其映射值的引用。 请注意,即使没有为元素指定映射值(使用其默认构造函数构造元素),这也会将容器大小增加1。

第一个准则

std::map<std::string, MyClass> Map;
//and add elements:
Map["someting"] = myObject;
  1. 您创建地图Map
  2. 您调用Map的下标运算符operator[] 假设密钥"something"不存在,它通过调用MyClass的默认构造函数创建与此密钥对应的MyClass实例。
  3. 下标运算符返回对此新创建的实例的非常量引用。
  4. 赋值运算符在Map调用MyClass实例的隐式或显式,复制或移动赋值运算符,将myObject作为参数发送给它。
  5. 假设赋值操作运行良好,myObject将分配给键。

第二个守则

MyClass& object = Map["something_new"];
//and then, initialize the object
object.method();
//and later I can use this map
Map["something_new"];
  1. 您通过调用MyClass的默认构造函数创建一个新的MyClass (假设它不存在)实例对应键"something_new"
  2. 您将获得该实例的引用。
  3. 你通过使用该引用来完成你的工作(即; call method() )。
  4. 稍后,您可以使用相同的密钥获得相同的引用。

结果

这里没有什么可比的。 第一个代码进行赋值,第二个代码调用方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM