Related
Consider this code
#include <map>
#include <memory>
using int_map = std::map<int, std::unique_ptr<int>>;
void f(int_map cl);
void f2() {
int_map cl;
f(cl);
}
Obviously this code does not compile because int_map cannot be copied
But when you compile using gcc:
g++ -Wall -c example.cpp
You get this:
In file included from /usr/include/c++/12.1.1/x86_64-pc-linux-gnu/bits/c++allocator.h:33,
from /usr/include/c++/12.1.1/bits/allocator.h:46,
from /usr/include/c++/12.1.1/bits/stl_tree.h:64,
from /usr/include/c++/12.1.1/map:60,
from example.cpp:1:
/usr/include/c++/12.1.1/bits/new_allocator.h: In instantiation of ‘void std::__new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const int, std::unique_ptr<int> >; _Args = {const std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >&}; _Tp = std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int> > >]’:
/usr/include/c++/12.1.1/bits/alloc_traits.h:516:17: required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(allocator_type&, _Up*, _Args&& ...) [with _Up = std::pair<const int, std::unique_ptr<int> >; _Args = {const std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >&}; _Tp = std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int> > >; allocator_type = std::allocator<std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int> > > >]’
/usr/include/c++/12.1.1/bits/stl_tree.h:595:32: required from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_construct_node(_Link_type, _Args&& ...) [with _Args = {const std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >&}; _Key = int; _Val = std::pair<const int, std::unique_ptr<int> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::unique_ptr<int> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int> > >; _Link_type = std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int> > >*]’
/usr/include/c++/12.1.1/bits/stl_tree.h:612:21: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::pair<const int, std::unique_ptr<int, std::default_delete<int> > >&}; _Key = int; _Val = std::pair<const int, std::unique_ptr<int> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::unique_ptr<int> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int> > >; _Link_type = std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int> > >*]’
/usr/include/c++/12.1.1/bits/stl_tree.h:529:32: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Alloc_node::operator()(_Arg&&) const [with _Arg = const std::pair<const int, std::unique_ptr<int> >&; _Key = int; _Val = std::pair<const int, std::unique_ptr<int> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::unique_ptr<int> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int> > >*]’
/usr/include/c++/12.1.1/bits/stl_tree.h:645:18: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_clone_node(_Link_type, _NodeGen&) [with bool _MoveValue = false; _NodeGen = std::_Rb_tree<int, std::pair<const int, std::unique_ptr<int> >, std::_Select1st<std::pair<const int, std::unique_ptr<int> > >, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int> > > >::_Alloc_node; _Key = int; _Val = std::pair<const int, std::unique_ptr<int> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::unique_ptr<int> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int> > >; _Link_type = std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int> > >*]’
/usr/include/c++/12.1.1/bits/stl_tree.h:1895:47: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_copy(_Link_type, _Base_ptr, _NodeGen&) [with bool _MoveValues = false; _NodeGen = std::_Rb_tree<int, std::pair<const int, std::unique_ptr<int> >, std::_Select1st<std::pair<const int, std::unique_ptr<int> > >, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int> > > >::_Alloc_node; _Key = int; _Val = std::pair<const int, std::unique_ptr<int> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::unique_ptr<int> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int> > >; _Link_type = std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int> > >*; _Base_ptr = std::_Rb_tree_node_base*]’
/usr/include/c++/12.1.1/bits/stl_tree.h:890:26: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_copy(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, _NodeGen&) [with bool _MoveValues = false; _NodeGen = std::_Rb_tree<int, std::pair<const int, std::unique_ptr<int> >, std::_Select1st<std::pair<const int, std::unique_ptr<int> > >, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int> > > >::_Alloc_node; _Key = int; _Val = std::pair<const int, std::unique_ptr<int> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::unique_ptr<int> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int> > >; _Link_type = std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int> > >*]’
/usr/include/c++/12.1.1/bits/stl_tree.h:901:29: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_copy(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&) [with _Key = int; _Val = std::pair<const int, std::unique_ptr<int> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::unique_ptr<int> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int> > >; _Link_type = std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int> > >*]’
/usr/include/c++/12.1.1/bits/stl_tree.h:939:23: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Rb_tree(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&) [with _Key = int; _Val = std::pair<const int, std::unique_ptr<int> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::unique_ptr<int> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::unique_ptr<int> > >]’
/usr/include/c++/12.1.1/bits/stl_map.h:217:7: required from here
/usr/include/c++/12.1.1/bits/new_allocator.h:175:11: error: use of deleted function ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int; _T2 = std::unique_ptr<int>]’
175 | { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/12.1.1/bits/stl_algobase.h:64,
from /usr/include/c++/12.1.1/bits/stl_tree.h:63:
/usr/include/c++/12.1.1/bits/stl_pair.h:195:17: note: ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int; _T2 = std::unique_ptr<int>]’ is implicitly deleted because the default definition would be ill-formed:
195 | constexpr pair(const pair&) = default; ///< Copy constructor
| ^~~~
/usr/include/c++/12.1.1/bits/stl_pair.h:195:17: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
In file included from /usr/include/c++/12.1.1/memory:76,
from example.cpp:2:
/usr/include/c++/12.1.1/bits/unique_ptr.h:514:7: note: declared here
514 | unique_ptr(const unique_ptr&) = delete;
| ^~~~~~~~~~
You will usually find tons of rubbish.
But WAIT in most cases we can filter out what we need using some tools
So try this
g++ -Wall -c example.cpp 2>&1 |grep example.cpp
We only care about errors in our code, so we can grep useful information by file name
But SADLY the command above prints this
from example.cpp:1:
from example.cpp:2:
This does not help AT ALL since we know clearly there are no error at line 1 and line 2 in example.cpp
We need the compiler to tell us where the error is, but it doesn't
It is impossible for a new c++ learner (even a professional c++ programmer) to locate the actual error at LINE 6 from those long and unreadable error output
Trivia:
Clang does not tell you the corrent error location, either. But if you use libc++ (-stdlib=libc++), it does. So maybe this is not a gcc problem, but a libstdc++ problem?
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
int main() {
map<pair<int,int>,pair<int,int>> items;
items.insert(make_pair(1,20),make_pair(0,0));
items.insert(make_pair(2,10),make_pair(0,0));
items.insert(make_pair(3,30),make_pair(0,0));
items.insert(make_pair(4,5),make_pair(0,0));
items.insert(make_pair(5,35),make_pair(0,0));
map<pair<int,int>,pair<int,int>>::iterator it;
cout<<"Class ID:\t\t\tSamples:\t\t\tTP:\t\t\tPrecision:"<<endl;
for(it = items.begin();it!=items.end();++it)
{
cout<<(it->first).first<<"\t\t\t"<<(it->first).second<<"\t\t\t"<<(it->second).first<<"\t\t\t"<<(it->second).second<<endl;
}
}
I have a code like this but i can't print my values. Can someone help me please?
I'm getting interesting compiler error :
Here is the text of the error :
In file included from C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/map:60,
from C:\Users\Fatih\Desktop\clion\quiz3\main.cpp:2:
C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h: In instantiation of 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_II, _II) [with _InputIterator = std::pair<int, int>; _Key = std::pair<int, int>; _Val = std::pair<const std::pair<int, int>, std::pair<int, int> >; _KeyOfValue = std::_Select1st<std::pair<const std::pair<int, int>, std::pair<int, int> > >; _Compare = std::less<std::pair<int, int> >; _Alloc = std::allocator<std::pair<const std::pair<int, int>, std::pair<int, int> > >]':
C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_map.h:893:4: required from 'void std::map<_Key, _Tp, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _InputIterator = std::pair<int, int>; _Key = std::pair<int, int>; _Tp = std::pair<int, int>; _Compare = std::less<std::pair<int, int> >; _Alloc = std::allocator<std::pair<const std::pair<int, int>, std::pair<int, int> > >]'
C:\Users\Fatih\Desktop\clion\quiz3\main.cpp:10:48: required from here
C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:2467:28: error: no match for 'operator++' (operand type is 'std::pair<int, int>')
for (; __first != __last; ++__first)
^~~~~~~~~
C:/PROGRA~1/MINGW-~1/X86_64~1.0-P/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:2468:29: error: no match for 'operator*' (operand type is 'std::pair<int, int>')
_M_insert_unique_(end(), *__first, __an);
^~~~~~~~
std::map::insert takes a parameter of value_type which is std::pair<const Key, Value>. That means you need to combine make_pair(1,20),make_pair(0,0) into a single parameter so you can call the function. That would look like
items.insert({make_pair(1,20),make_pair(0,0)});
// ^curly braces create value_type^
items.insert({make_pair(2,10),make_pair(0,0)});
items.insert({make_pair(3,30),make_pair(0,0)});
items.insert({make_pair(4,5),make_pair(0,0)});
items.insert({make_pair(5,35),make_pair(0,0)});
Alternatively you can use emplace which will take parameters to construct a value_type. That lets you get away without using the curly braces and looks like
items.emplace(make_pair(1,20),make_pair(0,0));
items.emplace(make_pair(2,10),make_pair(0,0));
items.emplace(make_pair(3,30),make_pair(0,0));
items.emplace(make_pair(4,5),make_pair(0,0));
items.emplace(make_pair(5,35),make_pair(0,0));
I got this example about implementing generic memoization in C++. However, as someone made notice in this comment, the original code makes 2 lookups, while the code below makes only one.
The only problem is that there is an error at the second return that I don't understand.
template <typename ReturnType, typename... Args>
std::function<ReturnType (Args...)> memoize(std::function<ReturnType (Args...)> func)
{
std::map<std::tuple<Args...>, ReturnType> cache;
return ([=](Args... args) mutable {
std::tuple<Args...> t(args...);
auto range = cache.equal_range(t);
if (range.first != range.second) return (*range.first).second;
return (*cache.insert(range.first, func(args...))).second;
});
}
Compiler error:
In instantiation of 'memoize(std::function<_Res(_ArgTypes ...)>)::<lambda(Args ...)> mutable [with ReturnType = int; Args = {int, int}]':
14:36: required from 'struct memoize(std::function<_Res(_ArgTypes ...)>) [with ReturnType = int; Args = {int, int}]::<lambda(int, int)>'
16:6: required from 'std::function<_Res(_ArgTypes ...)> memoize(std::function<_Res(_ArgTypes ...)>) [with ReturnType = int; Args = {int, int}]'
34:56: required from here
14:9: error: no matching function for call to 'std::map<std::tuple<int, int>, int, std::less<std::tuple<int, int> >, std::allocator<std::pair<const std::tuple<int, int>, int> > >::insert(std::_Rb_tree_iterator<std::pair<const std::tuple<int, int>, int> >&, int)'
14:9: note: candidates are:
In file included from /usr/include/c++/4.9/map:61:0,
from 1:
/usr/include/c++/4.9/bits/stl_map.h:629:7: note: std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const value_type&) [with _Key = std::tuple<int, int>; _Tp = int; _Compare = std::less<std::tuple<int, int> >; _Alloc = std::allocator<std::pair<const std::tuple<int, int>, int> >; typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator = std::_Rb_tree_iterator<std::pair<const std::tuple<int, int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const std::tuple<int, int>, int>]
insert(const value_type& __x)
^
/usr/include/c++/4.9/bits/stl_map.h:629:7: note: candidate expects 1 argument, 2 provided
/usr/include/c++/4.9/bits/stl_map.h:637:9: note: template<class _Pair, class> std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(_Pair&&) [with _Pair = _Pair; <template-parameter-2-2> = <template-parameter-1-2>; _Key = std::tuple<int, int>; _Tp = int; _Compare = std::less<std::tuple<int, int> >; _Alloc = std::allocator<std::pair<const std::tuple<int, int>, int> >]
insert(_Pair&& __x)
^
/usr/include/c++/4.9/bits/stl_map.h:637:9: note: template argument deduction/substitution failed:
14:9: note: candidate expects 1 argument, 2 provided
In file included from /usr/include/c++/4.9/map:61:0,
from 1:
/usr/include/c++/4.9/bits/stl_map.h:650:7: note: void std::map<_Key, _Tp, _Compare, _Alloc>::insert(std::initializer_list<std::pair<const _Key, _Tp> >) [with _Key = std::tuple<int, int>; _Tp = int; _Compare = std::less<std::tuple<int, int> >; _Alloc = std::allocator<std::pair<const std::tuple<int, int>, int> >]
insert(std::initializer_list<value_type> __list)
^
/usr/include/c++/4.9/bits/stl_map.h:650:7: note: candidate expects 1 argument, 2 provided
/usr/include/c++/4.9/bits/stl_map.h:679:7: note: 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::tuple<int, int>; _Tp = int; _Compare = std::less<std::tuple<int, int> >; _Alloc = std::allocator<std::pair<const std::tuple<int, int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::tuple<int, int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::tuple<int, int>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair<const std::tuple<int, int>, int>]
insert(const_iterator __position, const value_type& __x)
^
/usr/include/c++/4.9/bits/stl_map.h:679:7: note: no known conversion for argument 2 from 'int' to 'const value_type& {aka const std::pair<const std::tuple<int, int>, int>&}'
/usr/include/c++/4.9/bits/stl_map.h:690:9: note: template<class _Pair, class> 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; <template-parameter-2-2> = <template-parameter-1-2>; _Key = std::tuple<int, int>; _Tp = int; _Compare = std::less<std::tuple<int, int> >; _Alloc = std::allocator<std::pair<const std::tuple<int, int>, int> >]
insert(const_iterator __position, _Pair&& __x)
^
/usr/include/c++/4.9/bits/stl_map.h:690:9: note: template argument deduction/substitution failed:
/usr/include/c++/4.9/bits/stl_map.h:686:32: error: no type named 'type' in 'struct std::enable_if<false, void>'
template<typename _Pair, typename = typename
^
/usr/include/c++/4.9/bits/stl_map.h:705:9: note: template<class _InputIterator> void std::map<_Key, _Tp, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _InputIterator = _InputIterator; _Key = std::tuple<int, int>; _Tp = int; _Compare = std::less<std::tuple<int, int> >; _Alloc = std::allocator<std::pair<const std::tuple<int, int>, int> >]
insert(_InputIterator __first, _InputIterator __last)
^
The error is inside your lambda:
auto range = cache.equal_range(t);
...
... cache.insert(range.first, func(args...)) ...
and is
14:9: error: no matching function for call to
'std::map<std::tuple<int, int>, int,...>
::insert(std::_Rb_tree_iterator<...>&, int)'
It's telling you that you're calling insert wrongly.
The range returned from equal_range is a pair of iterators - you need to dereference the first iterator and take the first (key) element, to get the key/value pair you want. That is, something like
cache.insert(range.first, make_pair(t, func(args...)))
In general, you can help yourself figure these errors out by:
simplifying your code (these big compound statements mean lots of things are happening, and there's lots of potential errors, on a single line),
by reading the error message carefully (it does list the column, and does say the problem is with insert,
and if all else fails by reproducing the error in a minimal example (removing code unrelated to the error reduces the number of issues to consider).
I would like to create a simple map like this:
std::map<const std::string, const std::string> mymap;
mymap.insert("foo", "bar");
when I try this, I get this error:
In file included from /usr/include/c++/4.8.2/map:60:0,
from /home/me/dev/some-project/blocks/mycompany/some-project/main.cpp:11:
/usr/include/c++/4.8.2/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_insert_unique_(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Arg&&) [with _Arg = const char&; _Key = const std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, const std::basic_string<char> >; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, const std::basic_string<char> > >; _Compare = std::less<const std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, const std::basic_string<char> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, const std::basic_string<char> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, const std::basic_string<char> > >]’:
/usr/include/c++/4.8.2/bits/stl_tree.h:1722:37: required from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_II, _II) [with _InputIterator = const char*; _Key = const std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, const std::basic_string<char> >; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, const std::basic_string<char> > >; _Compare = std::less<const std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, const std::basic_string<char> > >]’
/usr/include/c++/4.8.2/bits/stl_map.h:671:11: required from ‘void std::map<_Key, _Tp, _Compare, _Alloc>::insert(_InputIterator, _InputIterator) [with _InputIterator = const char*; _Key = const std::basic_string<char>; _Tp = const std::basic_string<char>; _Compare = std::less<const std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, const std::basic_string<char> > >]’
/home/me/dev/some-project/blocks/mycompany/some-project/main.cpp:38:57: required from here
/usr/include/c++/4.8.2/bits/stl_tree.h:1478:63: error: no match for call to ‘(std::_Select1st<std::pair<const std::basic_string<char>, const std::basic_string<char> > >) (const char&)’
= _M_get_insert_hint_unique_pos(__position, _KeyOfValue()(__v));
^
In file included from /usr/include/c++/4.8.2/string:48:0,
from /usr/include/c++/4.8.2/bits/locale_classes.h:40,
from /usr/include/c++/4.8.2/bits/ios_base.h:41,
from /usr/include/c++/4.8.2/ios:42,
from /usr/include/c++/4.8.2/ostream:38,
from /usr/include/c++/4.8.2/iostream:39,
from /home/me/dev/some-project/blocks/mycompany/some-project/main.cpp:10:
/usr/include/c++/4.8.2/bits/stl_function.h:486:12: note: candidates are:
struct _Select1st
^...
It goes on and on, but I cannot tell what the problem is from the error output.
I cannot paste the rest of it because stackoverflow says I have too much code and not enough text.
That's simply not how you use std::map<..>::insert in C++. You should insert a std::pair<std::string,std::string>(std::string("a"), std::string("b")). See your arbitrary C++ reference.
You might get away without using std::string("a"), because there's a std::string constructor that takes C strings.
You're using insert() when you should be using emplace() or operator[].
However, you can't use const std::string when using operator[].
std::map<std::string, std::string> mymap;
mymap["foo"] = "bar";
If you're really bent on using insert() and const std::string, you have to insert an std::pair<const std::string, const std::string>.
std::map<const std::string, const std::string> mymap;
std::pair<const std::string,const std::string> p("foo", "bar");
mymap.insert(p);
Then there's the C++11 way, using an initializer list:
std::map<const std::string, const std::string> mymap;
mymap.insert({ "foo", "bar" });
You can insert std::pair into a map using insert.
mymap.insert(std::pair<const std::string, const std::string>("a", "b"));
I want to put a moveable but not copyable type as a value in std::map. Here is some simple code to test the principle.
#include <map>
struct Foo
{
Foo ();
Foo (const Foo &) = delete;
Foo & operator = (const Foo &) = delete;
Foo (Foo &&) {}
Foo & operator = (Foo &&) {return *this;}
};
int main ()
{
std :: map <int, Foo> m;
m .insert (std :: make_pair (123, Foo ()));
}
I compile this with g++ test.cpp --std=c++0x (gcc version 4.5.1 on Ubuntu 12.04). There is a big ugly error as shown below. What is the problem?
In file included from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_algobase.h:66:0,
from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:62,
from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/map:60,
from test.cpp:1: test.cpp: In copy constructor ‘std::pair<const int, Foo>::pair(const std::pair<const int, Foo>&)’: /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_pair.h:72:5: instantiated from ‘std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = {const std::pair<const int, Foo>&}, _Val = std::pair<const int, Foo>]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/ext/new_allocator.h:111:4: instantiated from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*,
_Args&& ...) [with _Args = {const std::pair<const int, Foo>&}, _Tp = std::_Rb_tree_node<std::pair<const int, Foo> >, _Tp* = std::_Rb_tree_node<std::pair<const int, Foo> >*]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:394:8: instantiated from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val,
_KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::pair<const int, Foo>&}, _Key = int, _Val = std::pair<const int, Foo>, _KeyOfValue = std::_Select1st<std::pair<const int, Foo> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >, std::_Rb_tree_node<_Val>* = std::_Rb_tree_node<std::pair<const int, Foo> >*]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:899:42: instantiated from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_(const std::_Rb_tree_node_base*, const std::_Rb_tree_node_base*, const _Val&) [with _Key = int, _Val = std::pair<const int, Foo>, _KeyOfValue = std::_Select1st<std::pair<const int, Foo> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, Foo> >, const std::_Rb_tree_node_base* = const std::_Rb_tree_node_base*]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:1191:65: instantiated from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare,
_Alloc>::_M_insert_unique(const _Val&) [with _Key = int, _Val = std::pair<const int, Foo>, _KeyOfValue = std::_Select1st<std::pair<const int, Foo> >, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >]’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_map.h:501:41: instantiated from ‘std::pair<typename std::map<_Key, _Tp, _Compare,
_Alloc>::_Rep_type::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const std::map<_Key, _Tp, _Compare, _Alloc>::value_type&) [with _Key = int, _Tp = Foo, _Compare = std::less<int>, _Alloc = std::allocator<std::pair<const int, Foo> >, typename std::map<_Key, _Tp, _Compare, _Alloc>::_Rep_type::iterator = std::_Rb_tree_iterator<std::pair<const int, Foo> >, std::map<_Key,
_Tp, _Compare, _Alloc>::value_type = std::pair<const int, Foo>]’ test.cpp:20:43: instantiated from here test.cpp:7:2: error: deleted function ‘Foo::Foo(const Foo&)’ /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_pair.h:72:5: error: used here In file included from /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/map:60:0,
from test.cpp:1: /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h: In constructor ‘std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = {const std::pair<const int, Foo>&}, _Val = std::pair<const int, Foo>]’: /usr/local/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/bits/stl_tree.h:136:49: note: synthesized method ‘std::pair<const int, Foo>::pair(const std::pair<const int, Foo>&)’ first required here
I'm adding some details for future references: this bug as Quux pointed out was caused in gcc 4.5.1 by a problem in the move constructor for std::pair.
As of today the issue has been fixed and you should either upgrade your compiler version or workaround by using another version of the standard library.
Your code works just fine