Ayush Gupta
Ayush Gupta

Reputation: 1717

Inserting in map<string, STRUCT> error

I have a map with the struct defined as under:

struct kv_string {
        std::string value;
        long long exp_time;
        kv_string(const std::string& v): value(v), exp_time(-1) {}
};

Now when I'm trying to insert a new structure using

else if(qargs[0] == "set"){
    if(qargs.size()==3){
        kv_map.insert(std::make_pair( qargs[1], kv_string(qargs[2])));
    }
}

(qargs is a vector<string>), I get the following error:

> In file included from /usr/include/c++/4.8/map:61:0,
>                      from structures.h:5:
>     /usr/include/c++/4.8/bits/stl_map.h: In instantiation of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key,
> _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::basic_string<char>; _Tp = kv_string; _Compare =
> std::less<std::basic_string<char> >; _Alloc =
> std::allocator<std::pair<const std::basic_string<char>, kv_string> >;
> std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = kv_string;
> std::map<_Key, _Tp, _Compare, _Alloc>::key_type =
> std::basic_string<char>]’:
>     /usr/include/c++/4.8/stdexcept:281:48:   required from here
>     /usr/include/c++/4.8/bits/stl_map.h:469:59: error: no matching function for call to ‘kv_string::kv_string()’
>                __i = insert(__i, value_type(__k, mapped_type()));
>                                                                ^
>     /usr/include/c++/4.8/bits/stl_map.h:469:59: note: candidates are:
>     structures.h:11:9: note: kv_string::kv_string(const string&)
>              kv_string(const std::string& v): value(v), exp_time(-1) {}
>              ^
>     structures.h:11:9: note:   candidate expects 1 argument, 0 provided
>     structures.h:8:8: note: kv_string::kv_string(const kv_string&)
>      struct kv_string {
>             ^
>     structures.h:8:8: note:   candidate expects 1 argument, 0 provided
>     make: *** [server_main.o] Error 1

I have also tried adding an additional constructor kv_string(){}, but it gives a segmentation fault.

Upvotes: 0

Views: 777

Answers (2)

Mr.C64
Mr.C64

Reputation: 42924

The C++ compiler emitted this error message complaining about the lack of a default constructor for your kv_string class:

/usr/include/c++/4.8/bits/stl_map.h:469:59: error: no matching function for call to ‘kv_string::kv_string()’
           __i = insert(__i, value_type(__k, mapped_type()));

If you read the documentation for std::map::operator[], you'll see that the mapped type (in your case kv_string) must be default-constructible.

So, if it makes sense for your own design, you could just add a default constructor to your kv_string struct:

struct kv_string {
    // ...

    // Default constructor
    kv_string() : exp_time(-1 /* or whatever default value */) {}
};

As a side note, I would also mark your kv_string(const std::string&) constructor as explicit, to avoid implicit conversions from strings.

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 476990

You want this:

kv_map.insert(std::make_pair(qargs[1], kv_string(qargs[2]));

Or this:

kv_map.emplace(qargs[1], kv_string(qargs[2]);

Or, in C++17:

kv_map.try_emplace(qargs[1], qargs[2]);

The []-operator default-initializes a new element (if one doesn't exist for the given key), but your type kv_string is not default-constructible. So you cannot use that operator. The above operations are more powerful than the []-operator, too: they return an iterator to the element at the key, and information about whether the key already existed.

Upvotes: 3

Related Questions