减少冗余:向映射中插入元素

4

最近我开始熟悉C++11,其中auto关键字非常好用!只需输入:

for (auto bar : bars) {

使用格式化工具可以让代码更易读、更美观。但是,以下问题仍然会使你的工作势头全无:

foo.insert(std::pair<std::string, bar>("soVerbose", baz));

// As opposed to simply:

foo.insert("soVerbose", baz);

它现在的方式是否有充分的理由?有没有一些巧妙的方法可以使其更简洁?我知道[]操作符可以用于将元素插入到映射中,但其功能略有不同。


1
你可以使用 typedef std::pair<std::string, bar> tDataPair;,这样代码会更易读,例如 foo.insert(tDataPair("soVerbose", baz)); - EdChum
我同意 auto 可以被不负责任地使用,但是我认为使用它来避免为可以轻松推断的数据类型编写长声明类型并没有什么害处。 - Fault
4
使用C++告诉我开发者根本没在考虑汇编。我不明白问题出在哪里。 - MSalters
2
你实际想要写的是 foo.insert(std::make_pair("soVerbose", baz)); - Christian Rau
4个回答

15

使用emplace函数:

#include <iostream>
#include <utility>

#include <map>

int main()
{
    std::map<std::string, std::string> m;

    // uses pair's copy-constructor
    m.emplace(std::make_pair(std::string("a"), std::string("a")));

    // uses pair's converting copy constructor
    m.emplace(std::make_pair("b", "abcd"));

    // uses pair's template constructor
    m.emplace("d", "ddd");

    // uses pair's piecewise constructor
    m.emplace(std::piecewise_construct,
              std::forward_as_tuple("c"),
              std::forward_as_tuple(10, 'c'));

    for (const auto &p : m) {
        std::cout << p.first << " => " << p.second << '\n';
    }
}

1
引用来源是一种礼貌的表现。请逐字引用 http://en.cppreference.com/w/cpp/container/map/emplace。 - user2428400
2
@polkadotcadaver:是的,我已经在答案中放了那个页面的链接。 - dalle

11

你可以使用std::make_pair(),这会让它至少变得更好:

foo.insert(std::make_pair("soVerbose", baz));

实际上,我并不能完全确定这是否应该起作用,但我认为它是(我不太确定的原因是"soVerbose"可以被推断为char const[10],而类型char const[10]不可复制;至少在某个实现中曾经出现过这样的错误)。我还没有充分使用C++11,但我认为你也可以使用

foo.insert({ "notSoVerbose", baz });

这段代码肯定可以通过gccclang编译。

我看到别人已经提到了,但实际上,你确实应该使用:

foo.emplace("pretty cool", baz);

std::make_pair 对参数执行 decay_copy 操作,将数组转换为指针。 - Xeo

5

您可以使用make_pair,它会推断出成对元素的类型,而不需要您过于详细地声明它们:

foo.insert(std::make_pair("soVerbose", baz));

如果您使用的是C++11(例如最近的Visual Studio),请优先使用emplace:

foo.emplace("soVerbose", baz);

如果你使用emplace,为什么还要用make_pairemplace可以转发构造函数参数。 - Lightness Races in Orbit
@LightnessRacesinOrbit 我正在输入编辑内容的时候 :) - user2428400
1
不错 :) 顺便说一句,即使是最新的Visual Studio CTP在C++11支持方面也有些悲惨。可以说,Clang或GCC 4.8会更好一些。 - Lightness Races in Orbit
1
@LightnessRacesinOrbit 在谈论这个问题的特性时,尤其是考虑到你对“最近”的定义与我相符,使用“可悲”这个词是不恰当的。 - Christian Rau

0

为了减少冗长,可以写成:

foo.emplace("soVerbose", baz);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接