Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference as key in std::map

Tags:

c++

reference

map

Suppose some data structure:

typedef struct {
    std::string s;
    int i;
} data;

If I use the field data.s as key when adding instances of data in a map of type std::map<std::string&, data>, do the string gets copied? Is it safe to erase an element of the map because the reference will become invalid?

Also do the answers to these questions also apply to an unordered_map?

EDIT:

This is my current solution... but adding iterator to the map is UGLY:

typedef struct {
    const std::string* s;
    int i;
} data;

std::map<std::string, data> map;
typedef std::map<std::string, data>::iterator iterator;

// add an element to the map
iterator add_element(const std::string& s) {
    std::pair<iterator, bool> p = states.insert(std::make_pair(s, data()));
    iterator i = p.first;
    if(p.second) {
        data& d = (*i).second;
        d.s = &(*i).first;
    }
    return i;
}
like image 425
Giovanni Funchal Avatar asked Jul 13 '10 09:07

Giovanni Funchal


People also ask

Can you store references in a map C++?

The reason why you can't store them in a map is purely semantic; you have to initialize a reference when it's created and you can't change it afterward anymore. This doesn't mesh with the way a map works.

Can pair be a key in map C++?

A C++ map is a way to store a key-value pair. A map can be declared as follows: #include <iostream> #include <map> map<int, int> sample_map; Each map entry consists of a pair: a key and a value.

Can pointer be key of a map?

C++ standard provided specialisation of std::less for pointers, so yes you can safely use them as map keys etc.

Does map insert copy or reference?

Yes -- when you insert an item into an std::map, you pass it by value, so what it contains is a copy of what you passed.


1 Answers

C++11

Since C++11 reference wrapper is part of standard.

#include <functional> 

std::map<std::reference_wrapper<std::string>, data>

Using Boost

You may want to take a look at boost.ref. It provides a wrapper that enables references to be used in STL-containers like this:

std::map<boost::reference_wrapper<std::string>, data>
like image 158
Björn Pollex Avatar answered Sep 26 '22 22:09

Björn Pollex