代码之家  ›  专栏  ›  技术社区  ›  quantumwell

将空向量放入std::map()

  •  2
  • quantumwell  · 技术社区  · 6 年前

    如何将空向量放置到 std::map ?例如,如果我有 std::map<int, std::vector<int>> ,我想要 map[4] 包含空 std::vector<int> ,我能叫什么?

    5 回复  |  直到 6 年前
        1
  •  3
  •   Max Langhof    6 年前

    如果您使用 operator[](const Key&) ,地图将自动放置 值已初始化 (即在 std::vector ,则, 默认构造 )如果访问不存在的元素,则返回值。请参见此处:

    http://en.cppreference.com/w/cpp/container/map/operator_at

    (自C++11以来,细节有点复杂,但在您的情况下,这才是最重要的)。

    这意味着如果你的地图是空的 map[4] ,它将很容易为您提供对空(默认构造)向量的引用。分配一个空向量是不必要的,尽管它可能会使您的意图更加明确。

    演示: https://godbolt.org/g/rnfW7g

        2
  •  2
  •   Richard Hodges    6 年前

    不幸的是,严格正确的答案确实是使用 std::piecewise_construct 作为第一个参数,后跟两个元组。第一个表示创建键(4)的参数,第二个表示创建向量(空参数集)的参数。

    看起来是这样的:

    map.emplace(std::piecewise_construct,   // signal piecewise construction
                std::make_tuple(4),         // key constructed from int(4)
                std::make_tuple());         // value is default constructed
    

    当然,这看起来很难看,其他选择也会奏效。它们甚至可能不会在优化的构建中生成更多的代码:

    这一个概念上调用默认的构造和移动分配,但优化者很可能会看穿它。

    map.emplace(4, std::vector<int>());
    

    这一个调用默认构造,然后调用副本分配。不过,乐观主义者很可能会看穿它。

    map[4] = {};
    
        3
  •  2
  •   Community Romance    4 年前

    为了确保将空向量放置在位置4,您只需尝试 clear 位置4处的向量。

    std::map<int, std::vector<int>> my_map;
    my_map[4].clear();
    

    正如其他人所提到的,索引操作符 std::map 将在指定索引处构造空值(如果不存在)。如果是这样的话 清楚的 是多余的。但是,如果 std::vector<int> 已存在,调用 清楚的 用于清除那里的向量,从而得到一个空向量。

    这可能比我以前分配给 {} (见下文),因为我们可能计划将元素添加到位置4的向量中,并且我们不会以这种方式支付任何新分配的成本。此外,如果以前使用 my_map[4] 表示将来的使用情况,那么我们的新向量最终可能会调整到与以前几乎相同的大小,这意味着我们可以节省重新分配成本。


    以前的方法:

    仅分配给 {} 容器应在此处正确构造一个空向量:

    std::map<int, std::vector<int>> my_map;
    my_map[4] = {};
    std::cout << my_map.size() << std::endl; // prints 1
    

    Demo

    编辑:正如Jodocus提到的,如果你知道 标准::映射 尚未包含 vector 在位置4,然后简单地尝试访问该位置的向量将默认构造一个,例如:

    std::map<int, std::vector<int>> my_map;
    my_map[4]; // default-constructs a vector there
    
        4
  •  0
  •   Clearer    6 年前

    最简单的解决方案有什么问题? std::map[4] = {};

    在现代C++中,这应该不需要或至少很少的开销就可以完成您想要的任务。

    如果必须使用 emplace ,我能想到的最佳解决方案是:

    std::map<int, std::vector<int>> map;
    map.emplace(4, std::vector<int>());
    
        5
  •  -1
  •   Abhishek Keshri    6 年前

    将逐段\u构造与std::make\u tuple一起使用:

    map.emplace(std::piecewise_construct, std::make_tuple(4), std::make_tuple());
    

    我们在位置4插入一个空向量。

    如果有一个一般情况,比如,放置一个大小为100的向量,填充10,那么:

    map.emplace(std::piecewise_construct, std::make_tuple(4), std::make_tuple(100, 10));
    

    piecewise_construct :此常量值作为第一个参数传递,用于构造pair对象,以选择通过将两个元组对象的元素转发到各自的构造函数来就地构造其成员的构造函数形式。