0

I am trying to create a map which contains the objects with different arguments.

But I found that after inserting the pair, the object will be destroyed.

If I try to use the function in this object.For example:

#include <map>
#include <iostream>

class Test{
    public:
        Test(double value) : value_(value){}
        ~Test(){std::cout<< "destroyed";}
        void plusone()  {value_ += 1;}
    private:
        double value_;
};

int main(){
    std::map<long, Test> map;

    map.insert(std::make_pair(1, Test(1.2)));
    map[1].plusone();
    return 0;
}

It will show: [Error] no matching function for call to 'Class::Class()'

[Note] candidate expects 1 argument, 0 provided

How can I do this?

CHOCOLEO
  • 363
  • 2
  • 9
  • In your case, it seems that you may use `map::at` (throw if not found) instead of `map::operator[]` (try to insert default object, and return inserted/found object). – Jarod42 Mar 02 '16 at 00:32

2 Answers2

1

The syntax map[1] can only be used when the mapped type has a default constructor. This is because if the key is not found then a default-constructed object is inserted, but the compiler has to generate code for this at compile-time.

If you do not want to add a default constructor then you have to use different lookup code, e.g.:

auto it = map.find(1);
if ( it != map.end() )
    it->second.memberfuncion();

Also, your error message has nothing to do with destroying objects, as your title mentions.


In the code map.insert(std::make_pair(1, Class(argument)));, you create a temporary object Class(argument), and copy that into the map. Then the temporary object is destroyed.

If you want to avoid this and construct directly in the map, use map.emplace(1, argument);.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Note that `emplace()` is only available in C++11 and later. – Remy Lebeau Mar 02 '16 at 00:08
  • thank you so much ,very detail explanation. btw which one you prefer ? syntax [ ] or .find – CHOCOLEO Mar 02 '16 at 00:14
  • yes, in C++03 there is no option but to copy the object in – M.M Mar 02 '16 at 00:14
  • @CHOCOLEO well I prefer `[]` personally but as I explain in my answer, for some `Class`es it is not possible – M.M Mar 02 '16 at 00:15
  • @M.M Would you like to give one example? as I though there is no harm adding a default constructor to the class. Thanks – CHOCOLEO Mar 02 '16 at 00:20
  • @CHOCOLEO my answer includes an example of `find`, and your question includes an example of `[]` (if you added a default constructor) – M.M Mar 02 '16 at 00:46
0

Item access via map.operator[] requires your mapped type to be default constructible.

If it is not default constructible, use map.find which has no such requirement.

donkopotamus
  • 22,114
  • 2
  • 48
  • 60