2

ALL, I have a following code:

In .h file:

struct Foo
{
   int ma;
   double mb;
   Foo(int a, double b)
   {
        ma = a;
        mb = b;
   }
   Foo()
   {
        ma = 0;
        mb = 0.0;
   }
};

class MyClass
{
public:
    MyClass();
private:
     std::map<std::string,Foo> m_map;
};

In .cpp file:

MyClass::MyClass()
{
    m_map["1"] = Foo( 1, 0.1 );
    m_map["2"] = Foo( 2, 0.2 );
    m_map["3"] = Foo( 3, 0.3 );
}

What is the easiest way to assign Foo( 0, 0 ) to m_map["2"]?

I can simply write

m_map["2"] = Foo( 0, 0 );

but in this case a new variable of the type Foo will be created.

Also, I don't have a loop and so can't really use iterators...

Thank you.

5 Answers 5

3

You can simply write:

m_map["2"];

Here's a quote from cppreference about std::map::operator[]:

Inserts a new element to the container using key as the key and a default constructed mapped value and returns a reference to the newly constructed mapped value.

So your default constructor will be called if you mereley try to "get" the value.

Sign up to request clarification or add additional context in comments.

Comments

2

If I understand you correctly, you can just write

m_map["2"].ma = 0;
m_map["2"].mb = 0;

Although I don't see why

m_map["2"] = Foo(0,0); //or just Foo() because of the overloaded constructor

is a problem.

3 Comments

Ah, yes, it's a struct, not a class. So ma and mb are public, not private. [I never use structs with constructors when I write code - a struct is just plain data, classes have constructors and members - makes it easier to see quickly what's what]
@Mats Peterson, yes, just simple structure. No point of using the class for just this data holder.
But then, in my book, they shouldn't have constructors either!
1

C++ uses copy semantics and containers are keeping copies of what you put in them. Please also note that the library is free to make copies of the objects in containers (e.g. std::vector on reallocation) and it's assumed that the copy of an object is equivalent to the object.

If copying is a problem for you (because of performance or because of semantic) then the solution is to add a level of indirection and placing inside the map smart pointers to the objects or proxies instead of the real objects themselves.

This way the number of copies or temporaries created by the library will be irrelevant.

Comments

0

I can simply write

m_map["2"] = Foo( 0, 0 );

but in this case a new variable of the type Foo will be created.

No, it creates a copy of the Foo( 0, 0) instance in the maps internal store.

Comments

0

Since you do not have a method to alter the values of a Foo, yes, just assign the map["2"] with a new object. The old one will be overwritten - since it's a copy of the original object anyways, it makes no difference. Your Foo(0,0) only lives for a very short time anyways.

Alternatively, you could add a Foo::SetAB(int a, double b) { ma = a; mb = b; } function (or two functions to set a and b, or a clear function that sets both to zero, or some other variation on this theme. Then use m_map["2"].SetAB(0, 0); - in this case, there isn't much difference between the options, but if Foo was some complicated object that took a lot of "effort" to create (e.g. has lots of members, with lots of values, memory to allocate, strings to store, etc, etc) it can be very benefical to have a function to change the member variabls.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.