Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decreasing verbosity: inserting elements into map

I've been getting familiar with C++11 lately, and the auto keyword is great! Typing:

for (auto bar : bars) {

is oh-so satisfying. Keeps code readable and pretty. What still feels like it stops all your momentum is the following:

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

// As opposed to simply:

foo.insert("soVerbose", baz);

Is there a good reason it is the way it is? And is there some neat way of making it less verbose? I know the [] operator can be used for inserting elements into maps, but the functionality is slightly different.

like image 253
Fault Avatar asked Nov 28 '22 07:11

Fault


2 Answers

Use the emplace function:

#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';
    }
}
like image 188
dalle Avatar answered Dec 05 '22 10:12

dalle


You can use std::make_pair() which makes it, at least, a bit better:

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

Actually, I'm not entirely sure whether this is meant to work but I think it is (the reason I'm not quite sure is that "soVerbose" could be deduced as char const[10] and the type char const[10] isn't copyable; that was an error, at least, in some implementation at some point). I'm not, yet, using C++11 enough but I think you can also use

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

(the code certainly compiles with gcc and clang).

I see others already mentioned it but actually, you'd really use:

foo.emplace("pretty cool", baz);
like image 44
Dietmar Kühl Avatar answered Dec 05 '22 10:12

Dietmar Kühl