Unable to create a map of a class in C++ - c++

I'm not able to create a map of a certain class in C++.
Here is an example of what I'm talking about:
#include <iostream>
#include <map>
using namespace std;
class A {
private:
string name;
public:
A(){}
A(string name) : name(name){}
A(A& a) : name(a.name){}
~A(){}
string getName() { return name; }
};
int main() {
A a("a_name");
map<string, A> mapa;
mapa["a_name"] = a;
return 0;
}
When I compile the code, it gives me the following error:
In file included from /usr/include/c++/8/bits/stl_algobase.h:64,
from /usr/include/c++/8/bits/char_traits.h:39,
from /usr/include/c++/8/ios:40,
from /usr/include/c++/8/ostream:38,
from /usr/include/c++/8/iostream:39,
from prog.cpp:1:
/usr/include/c++/8/bits/stl_pair.h: In instantiation of ‘struct std::pair<const std::__cxx11::basic_string<char>, A>’:
/usr/include/c++/8/bits/stl_map.h:517:10: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = A; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, A> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = A; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::__cxx11::basic_string<char>]’
prog.cpp:20:15: required from here
/usr/include/c++/8/bits/stl_pair.h:303:17: error: ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const std::__cxx11::basic_string<char>; _T2 = A]’ declared to take const reference, but implicit declaration would take non-const
constexpr pair(const pair&) = default;
^~~~
Here is the code in ideone: https://www.ideone.com/sYsxcO
I need the map to save the object itself, and not just a pointer to it (in this case, the A objects).

Related

Mapping a pair to a struct

There's some code I've written which I have trouble with, but I've tried to write a simplified version of it to possibly reproduce the error I'm encountering:
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
struct test{
float y;
};
typedef pair<int, int> intpair;
map<intpair, test> mp;
void func(test &obj){
obj.y = 23.5;
}
int main () {
test* obj = new test;
auto key = make_pair(1,1);
mp.insert(key, obj);
func(*obj);
//cout << *(obj->y);
delete obj;
return 0;
}
What I would like to do is map a pair to a custom struct test that I have created. I get the following error:
main.cpp: In function ‘int main()’:
main.cpp:22:22: error: no matching function for call to ‘std::map, test>::insert(std::pair&, test*&)’
mp.insert(key, obj);
^
In file included from /usr/include/c++/6/map:61:0,
from /usr/include/x86_64-linux-gnu/c++/6/bits/stdc++.h:81,
from main.cpp:2:
/usr/include/c++/6/bits/stl_map.h:731:7: note: candidate: std::pair, std::_Select1st >, _Compare, typename __gnu_cxx::__alloc_traits<_Allocator>::rebind >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const value_type&) [with _Key = std::pair; _Tp = test; _Compare = std::less >; _Alloc = std::allocator, test> >; typename std::_Rb_tree<_Key, std::pair, std::_Select1st >, _Compare, typename __gnu_cxx::__alloc_traits<_Allocator>::rebind >::other>::iterator = std::_Rb_tree_iterator, test> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair, test>]
insert(const value_type& __x)
^~~~~~
/usr/include/c++/6/bits/stl_map.h:731:7: note: candidate expects 1 argument, 2 provided
/usr/include/c++/6/bits/stl_map.h:739:9: note: candidate: template std::pair, std::_Select1st >, _Compare, typename __gnu_cxx::__alloc_traits<_Allocator>::rebind >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(_Pair&&) [with _Pair = _Pair; = ; _Key = std::pair; _Tp = test; _Compare = std::less >; _Alloc = std::allocator, test> >]
insert(_Pair&& __x)
^~~~~~
/usr/include/c++/6/bits/stl_map.h:739:9: note: template argument deduction/substitution failed:
main.cpp:22:22: note: candidate expects 1 argument, 2 provided
mp.insert(key, obj);
^
In file included from /usr/include/c++/6/map:61:0,
from /usr/include/x86_64-linux-gnu/c++/6/bits/stdc++.h:81,
from main.cpp:2:
/usr/include/c++/6/bits/stl_map.h:752:7: note: candidate: void std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::initializer_list >) [with _Key = std::pair; _Tp = test; _Compare = std::less >; _Alloc = std::allocator, test> >]
insert(std::initializer_list<value_type> __list)
^~~~~~
/usr/include/c++/6/bits/stl_map.h:752:7: note: candidate expects 1 argument, 2 provided
/usr/include/c++/6/bits/stl_map.h:781:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, const value_type&) [with _Key = std::pair; _Tp = test; _Compare = std::less >; _Alloc = std::allocator, test> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator, test> >; std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator, test> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair, test>]
insert(const_iterator __position, const value_type& __x)
^~~~~~
/usr/include/c++/6/bits/stl_map.h:781:7: note: no known conversion for argument 1 from ‘std::pair’ to ‘std::map, test>::const_iterator {aka std::_Rb_tree_const_iterator, test> >}’
/usr/include/c++/6/bits/stl_map.h:792:9: note: candidate: template std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator, _Pair&&) [with _Pair = _Pair; = ; _Key = std::pair; _Tp = test; _Compare = std::less >; _Alloc = std::allocator, test> >]
insert(const_iterator __position, _Pair&& __x)
^~~~~~
/usr/include/c++/6/bits/stl_map.h:792:9: note: template argument deduction/substitution failed:
main.cpp:22:22: note: cannot convert ‘key’ (type ‘std::pair’) to type ‘std::map, test>::const_iterator {aka std::_Rb_tree_const_iterator, test> >}’
mp.insert(key, obj);
^
In file included from /usr/include/c++/6/map:61:0,
from /usr/include/x86_64-linux-gnu/c++/6/bits/stdc++.h:81,
from main.cpp:2:
/usr/include/c++/6/bits/stl_map.h:807:9: note: candidate: template void std::map<_Key, _Tp, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _InputIterator = _InputIterator; _Key = std::pair; _Tp = test; _Compare = std::less >; _Alloc = std::allocator, test> >]
insert(_InputIterator __first, _InputIterator __last)
^~~~~~
/usr/include/c++/6/bits/stl_map.h:807:9: note: template argument deduction/substitution failed:
main.cpp:22:22: note: deduced conflicting types for parameter ‘_InputIterator’ (‘std::pair’ and ‘test*’)
mp.insert(key, obj);
Also, I'm sure that I'm going wrong in the way I access my obj's member y (cout statement commented out); How do I go about resolving these issues?
There are no overload of std::map::insert that takes a key and a value.
You can use operator[] to add a new element:
mp[key] = *obj;
Or std::map::insert_or_assign since C++17:
mp.insert_or_assign(key, *obj);
Another point is that type of obj is test* while the type of values of the map mp has type test. The pointer should be dereferenced (like my examples above) or the type of values should be changed to pointers to do this insertion.

Creating a Variant class and std::map<Variant, Variant>

I craeted a simple Variant class to store string, integer, double, etc. I'm trying to use a map of type std::map<Variant, Variant> but I'm getting this strange error:
In file included from /usr/include/c++/7/string:48:0,
from /home/dev/proj/cpp/common/Variant.h:3,
from /home/dev/proj/cpp/common/Event.h:3,
from /home/dev/proj/cpp/common/Event.cpp:1:
/usr/include/c++/7/bits/stl_function.h: In instantiation of 'constexpr bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Variant]':
/usr/include/c++/7/bits/stl_map.h:511:32: required from 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = Variant; _Tp = Variant; _Compare = std::less<Variant>; _Alloc = std::allocator<std::pair<const Variant, Variant> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = Variant; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = Variant]'
/home/dev/orwell/cpp/common/Event.cpp:33:18: required from here
/usr/include/c++/7/bits/stl_function.h:386:20: error: no match for 'operator<' (operand types are 'const Variant' and 'const Variant')
{ return __x < __y; }
~~~~^~~~~
This is my Variant class:
class Variant
{
public:
enum class Type
{
Integer,
Double,
String
};
Variant()
{
}
Variant(int integer)
{
this->type = Type::Integer;
setInteger(integer);
}
Variant(std::string string)
{
this->type = Type::String;
setString(string);
}
Variant(double _double)
{
this->type = Type::Double;
setDouble(_double);
}
Type type;
This is where the error is happening:
void Event::add(std::string key, std::string value) {
this->map[key] = Variant(value); //problem here
}
std::map is a sorted array. To do that it uses the < operator.
Thus, if you want to use Variant in a map (I believe this only applies to keys), you will need to supply an operator<() for it. You can find some examples here.
Or, you'll need a comparison function. That can work too.

std::map both costume compare functor and function/ lambda error

I have the following:
inputs:
Map1["Ram"] = 8;
Map1["Aam"] = 8;
Map1["Some"] = 2;
Map1["He"] = 5;
Map1["He"] = 6;
The expected output after insertion to the std::map<std::string, int> should be:
Output:
"Some" 2
"He" 5
"He" 6
"Aam" 8
Please note that:
sorting is according to the values, not keys.
the input Map1["Ram"] = 8; has overwritten by the next input Map1["Aam"] = 8;
Approach 1: Using a functor I was thinking to manage it. I have got this two errors:
||=== Build: Debug in MyTestProgram (compiler: GNU GCC Compiler) ===|
d:\mingw\include\c++\7.3.0\bits\stl_map.h||In instantiation of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = compare_functor; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::__cxx11::basic_string<char>]':|
D:\Programming\C++\CPP Programs\MyTestProgram\MyTestProgram.cpp|22|required from here|
d:\mingw\include\c++\7.3.0\bits\stl_map.h|511|error: no match for call to '(std::map<std::__cxx11::basic_string<char>, int, compare_functor>::key_compare {aka compare_functor}) (std::map<std::__cxx11::basic_string<char>, int, compare_functor>::key_type&, const std::__cxx11::basic_string<char>&)'|
D:\Programming\C++\CPP Programs\MyTestProgram\MyTestProgram.cpp|12|note: candidate: bool compare_functor::operator()(const T&, const T&) const|
D:\Programming\C++\CPP Programs\MyTestProgram\MyTestProgram.cpp|12|note: no known conversion for argument 1 from 'std::map<std::__cxx11::basic_string<char>, int, compare_functor>::key_type {aka std::__cxx11::basic_string<char>}' to 'const T& {aka const std::pair<std::__cxx11::basic_string<char>, int>&}'|
d:\mingw\include\c++\7.3.0\bits\stl_tree.h||In instantiation of 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_lower_bound(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, const _Key&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, int> >; |
d:\mingw\include\c++\7.3.0\bits\stl_tree.h|1187|required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, int> >; _Compare = compare_functor; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::_Rb_tree<_Key, _Val, _KeyOfVa|
d:\mingw\include\c++\7.3.0\bits\stl_map.h|1234|required from 'std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = compare_functor; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::__cxx11::basic_string<char|
d:\mingw\include\c++\7.3.0\bits\stl_map.h|509|required from 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = compare_functor; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::__cxx11::basic_string<char>]'|
Program.cpp|22|required from here|
d:\mingw\include\c++\7.3.0\bits\stl_tree.h|1872|error: no match for call to '(compare_functor) (const std::__cxx11::basic_string<char>&, const std::__cxx11::basic_string<char>&)'|
Program.cpp|12|note: candidate: bool compare_functor::operator()(const T&, const T&) const|
Program.cpp|12|note: no known conversion for argument 1 from 'const std::__cxx11::basic_string<char>' to 'const T& {aka const std::pair<std::__cxx11::basic_string<char>, int>&}'|
||=== Build failed: 2 error(s), 7 warning(s) (0 minute(s), 0 second(s)) ===|
Approach 2: The same logic I implemented with a lambda and I have got almost the same errors:
||=== Build: Debug in MyTestProgram (compiler: GNU GCC Compiler) ===|
d:\mingw\include\c++\7.3.0\bits\stl_map.h||In instantiation of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = bool (*)(const std::pair<std::__cxx11::basic_string<char>, int>&, const std::pair<std::__cxx11::basic_string<char>, int>&); _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std:|
Program.cpp|37|required from here|
d:\mingw\include\c++\7.3.0\bits\stl_map.h|511|error: invalid initialization of reference of type 'const std::pair<std::__cxx11::basic_string<char>, int>&' from expression of type 'std::map<std::__cxx11::basic_string<char>, int, bool (*)(const std::pair<std::__cxx11::basic_string<char>, int>&, const std::pair<std::__cxx11::basic_string<char>, int>&)>::key_type {aka std::__cxx11::basic_string<char>}'|
d:\mingw\include\c++\7.3.0\bits\stl_tree.h||In instantiation of 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_lower_bound(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, const _Key&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, int> >; |
d:\mingw\include\c++\7.3.0\bits\stl_tree.h|1187|required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, int>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, int> >; _Compare = bool (*)(const std::pair<std::__cxx11::basic_string<char>, int>&, const std::pair<std::__cxx11::basic_string<char>, int>&); _Alloc = |
d:\mingw\include\c++\7.3.0\bits\stl_map.h|1234|required from 'std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::lower_bound(const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = bool (*)(const std::pair<std::__cxx11::basic_string<char>, int>&, const std::pair<std::__cxx11::basic_string<char>, int>&); _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::__cxx11::ba|
d:\mingw\include\c++\7.3.0\bits\stl_map.h|509|required from 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::__cxx11::basic_string<char>; _Tp = int; _Compare = bool (*)(const std::pair<std::__cxx11::basic_string<char>, int>&, const std::pair<std::__cxx11::basic_string<char>, int>&); _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_|
Program.cpp|37|required from here|
d:\mingw\include\c++\7.3.0\bits\stl_tree.h|1872|error: invalid initialization of reference of type 'const std::pair<std::__cxx11::basic_string<char>, int>&' from expression of type 'const std::__cxx11::basic_string<char>'|
||=== Build failed: 2 error(s), 7 warning(s) (0 minute(s), 0 second(s)) ===|
I have referred many answers online. But most of them were considering either Key type or Value type while comparing using the functor/ lambda, which was not my case. I would like to compare both Value and Key compared while inserting to the map.
Can anybody explain to me why these implementations fail?
Secondly, what I should have done to get above result while inserting(PS: I would like to still keep string as my key to the map and if it is possible, I do not want any temporary maps to do this result.)?
Here is my code:
#include <iostream>
#include <map>
#include <string>
#include <tuple>
typedef std::pair<std::string, int> T;
typedef bool(*compare_functional_type)(const T&, const T&);
// Way - 1: using functor
struct compare_functor
{
bool operator()(const T& A ,const T& B)const
{
return std::tie(A.second, A.first) < std::tie(B.second, B.first);
// OR in other-words:
//return (A.second == B.second) ? A.first < B.first : A.second < B.second;
};
};
int main()
{
std::map<std::string, int, compare_functor> Map1;
Map1["Ram"] = 8;
Map1["Aam"] = 8;
Map1["Some"] = 2;
Map1["He"] = 5;
Map1["He"] = 6;
// Way - 2: using lambdas and function pointers
compare_functional_type Lambda = [](const T& A, const T& B)
{
return std::tie(A.second, A.first) < std::tie(B.second, B.first);
// OR in other-words:
//return (A.second == B.second) ? A.first < B.first : A.second < B.second;
};
std::map<std::string, int, compare_functional_type> Map2(Lambda);
Map2["Ram"] = 8;
Map2["Aam"] = 8;
Map2["Some"] = 2;
Map2["He"] = 5;
Map2["He"] = 6;
return 0;
}
std::map<int, std::string> is what you want.
To have your inverted syntax, you might use wrapper, something like:
class Wrapper
{
public:
Wrapper(std::map<int, std::string>& m, const std::string& s) : m(m), s(s) {}
void operator =(int k) { m[k] = s; }
private:
std::map<int, std::string>& m;
std::string s;
};
class InvertedMap
{
public:
Wrapper operator[](const std::string& s) { return {m, s}; }
auto begin() const { return m.begin(); }
auto end() const { return m.end(); }
private:
std::map<int, std::string> m;
};
And then:
InvertedMap Map1;
Map1["Ram"] = 8;
Map1["Aam"] = 8;
Map1["Some"] = 2;
Map1["He"] = 5;
Map1["He"] = 6;
for (const auto& p : Map1) {
std::cout << p.second << " " << p.first << std::endl;
}
// Output:
// Some 2
// He 5
// He 6
// Aam 8
Demo

How to call class member function from iterator of map in C++?

I am not able to call the show function using iterator of map. Is there any way to do this using iterator?
#include <iostream>
#include <string>
#include <map>
using namespace std;
class A
{
int i;
public:
A(int pi):i(pi) { cout<<"A()\n"; }
void show() const { cout<<i<<endl; }
~A() { cout<<"~A()\n"; }
};
int main()
{
map<char, A > mymap;
A a(9) , b(8) , c(7);
mymap['a'] = a;
mymap['b'] = b;
mymap['c'] = c;
map<char,A >::iterator it;
for(it = mymap.begin(); it != mymap.end() ; it++)
(*(it->second)).show();
return 0;
}
On using it->second.show(), I get the error below:
In file included from /usr/include/c++/4.9/bits/stl_map.h:63:0,
from /usr/include/c++/4.9/map:61,
from 3: /usr/include/c++/4.9/tuple: In instantiation of 'std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&,
std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>,
std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {char&&}; long
unsigned int ..._Indexes1 = {0ul}; _Args2 = {}; long unsigned int
..._Indexes2 = {}; _T1 = const char; _T2 = A]':
/usr/include/c++/4.9/tuple:1093:63: required from 'std::pair<_T1,
_T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {char&&}; _Args2 = {}; _T1 =
const char; _T2 = A]' /usr/include/c++/4.9/ext/new_allocator.h:120:4:
required from 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*,
_Args&& ...) [with _Up = std::pair; _Args = {const std::piecewise_construct_t&, std::tuple, std::tuple<>}; _Tp =
std::_Rb_tree_node >]'
/usr/include/c++/4.9/bits/alloc_traits.h:253:4: required from
'static std::_Require::__construct_helper<_Tp, _Args>::type>
std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&&
...) [with _Tp = std::pair; _Args = {const
std::piecewise_construct_t&, std::tuple, std::tuple<>}; _Alloc
= std::allocator > >; std::_Require::__construct_helper<_Tp, _Args>::type> =
void]' /usr/include/c++/4.9/bits/alloc_traits.h:399:57: required
from 'static decltype (_S_construct(__a, __p,
(forward<_Args>)(std::allocator_traits::construct::__args)...))
std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...)
[with _Tp = std::pair; _Args = {const
std::piecewise_construct_t&, std::tuple, std::tuple<>}; _Alloc
= std::allocator > >; decltype (_S_construct(__a, __p,
(forward<_Args>)(std::allocator_traits::construct::__args)...)) =
]' /usr/include/c++/4.9/bits/stl_tree.h:423:42: required
from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue,
_Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple, std::tuple<>}; _Key =
char; _Val = std::pair; _KeyOfValue =
std::_Select1st >; _Compare =
std::less; _Alloc = std::allocator >;
std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type =
std::_Rb_tree_node >*]'
/usr/include/c++/4.9/bits/stl_tree.h:1790:64: required from
'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator
std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple, std::tuple<>}; _Key =
char; _Val = std::pair; _KeyOfValue =
std::_Select1st >; _Compare =
std::less; _Alloc = std::allocator >;
std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator =
std::_Rb_tree_iterator >; std::_Rb_tree<_Key,
_Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator >]'
/usr/include/c++/4.9/bits/stl_map.h:519:8: required from
'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key,
_Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = char; _Tp = A; _Compare = std::less; _Alloc = std::allocator >;
std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = A; std::map<_Key,
_Tp, _Compare, _Alloc>::key_type = char]' 17:14: required from here /usr/include/c++/4.9/tuple:1104:70: error: no matching function for
call to 'A::A()'
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
^ /usr/include/c++/4.9/tuple:1104:70: note: candidates are: 9:5: note:
A::A(int) 9:5: note: candidate expects 1 argument, 0 provided 5:7:
note: constexpr A::A(const A&) 5:7: note: candidate expects 1
argument, 0 provided
1.it->second will return A directly, not A*, you should change
(*(it->second)).show();
to
(it->second).show();
2.std::map::operator[] needs type A to be DefaultConstructible.
Inserts value_type(key, T()) if the key does not exist.
But A doesn't have the default constructor, you could
mymap.insert({'a', a});
or as #Jarod42 suggested:
mymap.emplace('a', a);
to avoid A being default constructed.
First thing is that you need a default constructor in A:
A() {}
compiler will not create default constructor if you have provided any other c-tor.
second thing is how to call your function:
it->second.show();
how about this? friend.
#include <iostream>
#include <string>
#include <map>
using namespace std;
class A
{
int i;
public:
A(int pi=0):i(pi) { cout<<"A()\n"; }
void show() const { cout<<i<<endl; }
~A() { cout<<"~A()\n"; }
};
int main()
{
map<char, A > mymap;
A a(9) , b(8) , c(7);
mymap['a'] = a;
mymap['b'] = b;
mymap['c'] = c;
map<char,A >::iterator it;
for(it = mymap.begin(); it != mymap.end() ; it++)
it->second.show();
return 0;
}
this will solve your troubles
A(int pi=0):i(pi) { cout<<"A("<<pi<<")\n"; }
...
for(it = mymap.begin(); it != mymap.end() ; it++)
(it->second).show();
u should override operator = to make it work properly

Smart pointers and map in C++

I'm trying to execute this program with smart pointers:
//File user.h
#include <list>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <memory>
#include <map>
using namespace std;
class User {
string name;
int id;
public:
User(const string& name, int id) : name(name), id(id) {}
int getID() const {return id;}
~User(){}
};
//File main.c
#include "user.h"
using namespace std;
typedef std::shared_ptr<User> UserPtr;
typedef map<string, UserPtr> Dict;
int main()
{
Dict dict;
dict = new User("Adams", 666);
auto it = dict.find("Adams");
if (it == dict.end())
cout << "not found!" << endl;
else
cout << "id3: " << it->second->getID() << endl;
return 0;
}
I have tested it before with raw pointers (*) and it works. Nonetheless, when using smart pointers I get the following errors:
main.cpp: In function ‘int main()’:
main.cpp:15:10: error: no match for ‘operator=’ (operand types are ‘Dict {aka std::map<std::basic_string<char>, std::shared_ptr<User> >}’ and ‘User*’)
dict = new User("Adams", 666);
^
main.cpp:15:10: note: candidates are:
In file included from /usr/include/c++/4.8/map:61:0,
from user.h:10,
from main.cpp:3:
/usr/include/c++/4.8/bits/stl_map.h:264:7: note: std::map<_Key, _Tp, _Compare, _Alloc>& std::map<_Key, _Tp, _Compare, _Alloc>::operator=(const std::map<_Key, _Tp, _Compare, _Alloc>&) [with _Key = std::basic_string<char>; _Tp = std::shared_ptr<User>; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::shared_ptr<User> > >]
operator=(const map& __x)
^
/usr/include/c++/4.8/bits/stl_map.h:264:7: note: no known conversion for argument 1 from ‘User*’ to ‘const std::map<std::basic_string<char>, std::shared_ptr<User> >&’
/usr/include/c++/4.8/bits/stl_map.h:279:7: note: std::map<_Key, _Tp, _Compare, _Alloc>& std::map<_Key, _Tp, _Compare, _Alloc>::operator=(std::map<_Key, _Tp, _Compare, _Alloc>&&) [with _Key = std::basic_string<char>; _Tp = std::shared_ptr<User>; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::shared_ptr<User> > >]
operator=(map&& __x)
^
/usr/include/c++/4.8/bits/stl_map.h:279:7: note: no known conversion for argument 1 from ‘User*’ to ‘std::map<std::basic_string<char>, std::shared_ptr<User> >&&’
/usr/include/c++/4.8/bits/stl_map.h:300:7: note: std::map<_Key, _Tp, _Compare, _Alloc>& std::map<_Key, _Tp, _Compare, _Alloc>::operator=(std::initializer_list<std::pair<const _Key, _Tp> >) [with _Key = std::basic_string<char>; _Tp = std::shared_ptr<User>; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::shared_ptr<User> > >]
operator=(initializer_list<value_type> __l)
^
/usr/include/c++/4.8/bits/stl_map.h:300:7: note: no known conversion for argument 1 from ‘User*’ to ‘std::initializer_list<std::pair<const std::basic_string<char>, std::shared_ptr<User> > >’
Is the smart pointer wrongly declared?
Dict is std::map and you are trying to assign a pointer to a User to it which is wrong.
What you need is
dict["Adams"] = std::make_shared<User>("Adams", 666);