Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

need help with std::map

57 views
Skip to first unread message

SpreadTooThin

unread,
Apr 2, 2015, 11:33:28 PM4/2/15
to
This is my map.

std::map<string, std::vector<string> > myMap;

Given that key is a string and the element that it represents is a vector of strings:

How do I add an element to myMap?

std::string key = "abc";
std::vector<string> * empty = new std::vector<string>;
map[key]=*empty;

To add an element to the vector withing the map

std::vector<string> *myvect;
myvect = map[key];
*myvect->push_back(newstring);

Shouldn't I be using a refrence to an object rather than a pointer?

Ian Collins

unread,
Apr 2, 2015, 11:41:57 PM4/2/15
to
Just add the vector:

std::vector<string> empty;
map[key]=empty;

or if you just want a default initialised vector,

map[key];


--
Ian Collins

SpreadTooThin

unread,
Apr 2, 2015, 11:51:40 PM4/2/15
to
So when the line "std::vector<string> empty;" goes out of scope there is still a reference to it in the map and I can still use it?

Ian Collins

unread,
Apr 3, 2015, 1:11:08 AM4/3/15
to
SpreadTooThin wrote:
> On Thursday, April 2, 2015 at 9:41:57 PM UTC-6, Ian Collins wrote:
>> SpreadTooThin wrote:
>>> This is my map.
>>>
>>> std::map<string, std::vector<string> > myMap;
>>>
>>> Given that key is a string and the element that it represents is a vector of strings:
>>>
>>> How do I add an element to myMap?
>>>
>>> std::string key = "abc";
>>> std::vector<string> * empty = new std::vector<string>;
>>> map[key]=*empty;
>>>
>>> To add an element to the vector withing the map
>>>
>>> std::vector<string> *myvect;
>>> myvect = map[key];
>>> *myvect->push_back(newstring);
>>>
>>> Shouldn't I be using a refrence to an object rather than a pointer?
>>>
>> Just add the vector:
>>
>> std::vector<string> empty;
>> map[key]=empty;
>>
>> or if you just want a default initialised vector,
>>
>> map[key];
>
> So when the line "std::vector<string> empty;" goes out of scope there is still a reference to it in the map and I can still use it?

It's copied.

C++ isn't Java!

--
Ian Collins

SpreadTooThin

unread,
Apr 3, 2015, 1:11:15 PM4/3/15
to
std::vector<string> & key
Isn't this a reference... Doesn't it seem inefficient to be copying objects...
Like I'd rather use a pointer to an object but then I'd have to be careful about freeing it...






Jorgen Grahn

unread,
Apr 3, 2015, 1:33:52 PM4/3/15
to
On Fri, 2015-04-03, SpreadTooThin wrote:
> On Thursday, April 2, 2015 at 9:33:28 PM UTC-6, SpreadTooThin wrote:
>> This is my map.
>>
>> std::map<string, std::vector<string> > myMap;
>>
>> Given that key is a string and the element that it represents
>> is a vector of strings:
>>
>> How do I add an element to myMap?
>>
>> std::string key = "abc";
>> std::vector<string> * empty = new std::vector<string>;
>> map[key]=*empty;
>>
>> To add an element to the vector withing the map
>>
>> std::vector<string> *myvect;
>> myvect = map[key];
>> *myvect->push_back(newstring);
>>
>> Shouldn't I be using a refrence to an object rather than a pointer?
>
> std::vector<string> & key
> Isn't this a reference...

Yes.

> Doesn't it seem inefficient to be copying objects...
> Like I'd rather use a pointer to an object but then
> I'd have to be careful about freeing it...

All the standard library containers copy. They own the objects they
contain. That's the way it is. In the rare cases where this is
inefficient, you'd store pointers or smart pointers instead -- but I
don't think I ever had to, for that particular reason.

(And this design got even cheaper with C++11.)

Also see Ian Collins' posting.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Öö Tiib

unread,
Apr 3, 2015, 1:38:58 PM4/3/15
to
All 'std::map', 'std::vector' and 'std::string' are dynamic containers.
These can be copied or moved. Typically people copy since it is simpler
and does not make much difference in performance:

myMap.insert( std::make_pair( key, value ) );
// 'key' and 'value' are unchanged just copied from

If too lot of copying will go on and it does make difference them people
can change it:

myMap.insert(std::make_pair( std::move(key), std::move(value));
// 'key' and 'value' are in valid but unspecified state after move
Message has been deleted

Luca Risolia

unread,
Apr 3, 2015, 2:55:58 PM4/3/15
to
Il 03/04/2015 19:38, Öö Tiib ha scritto:

> If too lot of copying will go on and it does make difference them people
> can change it:
>
> myMap.insert(std::make_pair( std::move(key), std::move(value));
> // 'key' and 'value' are in valid but unspecified state after move
>

In principle, using an emplacement function forwarding its arguments to
the pair's constructor is a better alternative, as it can be more
efficient and should never be less efficient than insertion. In
particular, the proposed C++17's try_emplace() should definitely be a
better alternative than insertion for the case of "possible rejected
duplicates".

Öö Tiib

unread,
Apr 3, 2015, 7:13:08 PM4/3/15
to
It does look indeed shorter and more elegant.

myMap.emplace( std::move(key), std::move(value) );

I can't measure that it performs any better. Perhaps new
'std::make_pair' and 'std::map::insert' are combining perfect
forwarding cleverly enough that result is about same.

Also it might be worth to note that on cases when the inserting
code is fully certain that it is not attempt to insert a duplicate
it usually also has some hint available for 'insert' overload
that takes hint or 'emplace_hint'. Those perform slightly better
than without hint.

Melzzzzz

unread,
Apr 3, 2015, 11:07:21 PM4/3/15
to
On Thu, 2 Apr 2015 20:32:57 -0700 (PDT)
SpreadTooThin <bjobr...@gmail.com> wrote:

> This is my map.
>
> std::map<string, std::vector<string> > myMap;
>
> Given that key is a string and the element that it represents is a
> vector of strings:
>
> How do I add an element to myMap?

myMap["abc"].push_back(newstring);

>
> std::string key = "abc";
> std::vector<string> * empty = new std::vector<string>;
> map[key]=*empty;
>
> To add an element to the vector withing the map
>
> std::vector<string> *myvect;
> myvect = map[key];
> *myvect->push_back(newstring);
>
> Shouldn't I be using a refrence to an object rather than a pointer?

you can get reference:
std::vector<string>& abc = myMap["abc"];
no copying involved,

>

PS:

Why do you use map? unordered_map should now be prefered, that is, you
need map, only if you want ordered access.

Juha Nieminen

unread,
Apr 7, 2015, 4:34:49 AM4/7/15
to
SpreadTooThin <bjobr...@gmail.com> wrote:
> std::string key = "abc";
> std::vector<string> * empty = new std::vector<string>;
> map[key]=*empty;

Why are you doing it like that (leaking memory to boot)? What exactly
is the problem with:

std::vector<std::string> empty;
map["abc"] = empty;

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---
0 new messages