C++ Deep Copying a pointer to a map with pointer values - c++

I am having a bit of trouble deep copying a pointer to a map of pointer values.
std::map<string, TH1D*>* m_hist_split;
My current method:
I am using a class template that copies the map pair and initializes the value of the pair on the heap. the template then returns a map::type_value
#ifndef DEEPCOPY_H
#define DEEPCOPY_H
#include <map>
#include <algorithm>
namespace DeepCopy{
template<class A, class B>
struct MapPointerValue{
typedef typename std::map< A, B* >::value_type map_t;
map_t operator() (map_t p){
return std::make_pair(p.first, new B(*p.second) );
}
};
...
...
}
#endif
Inside my copy constructor I then attempt to deep copy my pointer to a map of pointer values.
Cutflow::Cutflow(const Cutflow& cpy){
m_hist_split = new map<string, TH1D*>;
transform(cpy.m_hist_split->begin(),cpy.m_hist_split->end(), inserter(m_hist_split, m_hist_split->begin()), DeepCopy::MapPointerValue<string, TH1D>() );
...
...
}
When compiling I then get an ugly error :-( :
Compiling src/Cutflow.cxx to obj/Cutflow.o
x86_64-slc5-gcc34-opt/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/bits/stl_iterator.h: In instantiation of 'std::insert_iterator<std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*>':
src/Cutflow.cxx:42: instantiated from here
x86_64-slc5-gcc34-opt/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/bits/stl_iterator.h:562: error: 'std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*' is not a class, struct, or union type
x86_64-slc5-gcc34-opt/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/bits/stl_iterator.h:572: error: 'std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*' is not a class, struct, or union type
x86_64-slc5-gcc34-opt/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/bits/stl_iterator.h:599: error: 'std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*' is not a class, struct, or union type
x86_64-slc5-gcc34-opt/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/bits/stl_iterator.h:608: error: 'std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*' is not a class, struct, or union type
x86_64-slc5-gcc34-opt/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/bits/stl_iterator.h: In function 'std::insert_iterator<_Container> std::inserter(_Container&, _Iterator) [with _Container = std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*, _Iterator = std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> >]':
src/Cutflow.cxx:42: instantiated from here
x86_64-slc5-gcc34-opt/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/bits/stl_iterator.h:648: error: 'std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*' is not a class, struct, or union type
x86_64-slc5-gcc34-opt/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/bits/stl_algo.h: In function '_OIter std::transform(_IIter, _IIter, _OIter, _UnaryOperation) [with _IIter = std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> >, _OIter = std::insert_iterator<std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*>, _UnaryOperation = DeepCopy::MapPointerValue<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D>]':
src/Cutflow.cxx:42: instantiated from here
x86_64-slc5-gcc34-opt/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/bits/stl_algo.h:4281: error: no match for 'operator=' in '__result.std::insert_iterator<_Container>::operator* [with _Container = std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*]() = DeepCopy::MapPointerValue<A, B>::operator()(typename std::map<A, B*, std::less<_Key>, std::allocator<std::pair<const A, B*> > >::value_type) [with A = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, B = TH1D](std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*>(((const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*>&)((const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*>*)__first.std::_Rb_tree_iterator<_Tp>::operator* [with _Tp = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*>]()))))'
x86_64-slc5-gcc34-opt/bin/../lib/gcc/x86_64-unknown-linux-gnu/4.3.2/../../../../include/c++/4.3.2/bits/stl_iterator.h:559: note: candidates are: std::insert_iterator<std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*>& std::insert_iterator<std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*>::operator=(const std::insert_iterator<std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, TH1D*> > >*>&)
Any ideas what I am doing wrong.
Also,
is what I am doing correct?
:-D

In the following line
transform(cpy.m_hist_split->begin(),cpy.m_hist_split->end(), inserter(m_hist_split, m_hist_split->begin()), DeepCopy::MapPointerValue<string, TH1D>() );
you have mistakenly called the inserter function with a pointer to a map as the first parameter instead of a reference.
For completeness, inserter is defined in §24.5.2.6.5 like this:
template <class Container>
insert_iterator<Container> inserter(Container& x, typename Container::iterator i);
Returns: insert_iterator(x, i)
In this case, a simple typo caused a big headache.

Related

Gtest compiler error when invoking function with rvalue argument

I cant for the love of god understand what this compiler error is trying to tell me:
Reproduced here on godbolt: https://godbolt.org/z/v3M5hEbdv
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include <string>
#include <functional>
#include <vector>
class MyService {
public:
virtual ~MyService() = default;
virtual void bar(
std::function<void (std::vector<std::string>&&)> onSuccess
) = 0;
};
class MyServiceMock : public MyService
{
public:
MOCK_METHOD(
void,
bar,
(std::function<void(std::vector<std::string>&&)> onSuccess),
(override)
);
};
[[maybe_unused]]
void foo() {
testing::NiceMock<MyServiceMock> myService;
EXPECT_CALL(myService, bar(testing::_))
.Times(testing::Exactly(1))
.WillOnce(testing::DoAll(
testing::Return(),
testing::InvokeArgument<0>(
std::vector<std::string>({"hello", "world"})
)
));
}
int main() {
return 0;
}
The compiler error :
Output of x86-64 gcc 11.2 (Compiler #1)
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/unique_ptr.h:37,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/memory:76,
from /opt/compiler-explorer/libs/googletest/trunk/googletest/include/gtest/gtest.h:55,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple: In instantiation of 'struct std::tuple_element<0, std::tuple<> >':
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/utility:118:11: required by substitution of 'template<long unsigned int __i, class _Tp> using __tuple_element_t = typename std::tuple_element::type [with long unsigned int __i = 0; _Tp = std::tuple<>]'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple:1403:5: required by substitution of 'template<long unsigned int __i, class ... _Elements> constexpr std::__tuple_element_t<__i, std::tuple<_UTypes ...> >&& std::get(const std::tuple<_UTypes ...>&&) [with long unsigned int __i = 0; _Elements = {}]'
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-more-actions.h:515:22: required by substitution of 'template<class ... Args> decltype (testing::internal::InvokeArgument(get<0>(std::forward_as_tuple((forward<Args>)(testing::internal::InvokeArgumentAction<index, Params ...>::operator()::args)...)), declval<const std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&>())) testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::operator()<Args ...>(Args&& ...) const [with Args = {}]'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/type_traits:2466:26: required by substitution of 'template<class _Fn, class ... _Args> static std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)), std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn = testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&; _Args = {}]'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/type_traits:2477:55: required from 'struct std::__result_of_impl<false, false, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&>'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/type_traits:2482:12: [ skipping 3 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/std_function.h:344:8: required by substitution of 'template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = typename std::enable_if<_Cond::value, _Tp>::type [with _Cond = std::function<void()>::_Callable<testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__invoke_result<testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&> >; _Tp = void; _Res = void; _ArgTypes = {}]'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/std_function.h:413:9: required by substitution of 'template<class _Functor, class, class> std::function<void()>::function(_Functor) [with _Functor = testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >; <template-parameter-1-2> = void; <template-parameter-1-3> = <missing>]'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/type_traits:906:30: required from 'struct std::__is_constructible_impl<std::function<void()>, const testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&>'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/type_traits:911:12: required from 'struct std::is_constructible<std::function<void()>, const testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&>'
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-actions.h:466:7: required by substitution of 'template<class G, class> testing::Action<void(std::function<void(std::vector<std::__cxx11::basic_string<char> >&&)>)>::Action(G&&) [with G = const testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&; <template-parameter-1-2> = <missing>]'
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-actions.h:1061:56: required from 'testing::internal::DoAllAction<Actions>::operator testing::Action<R(Args ...)>() const [with R = void; Args = {std::function<void(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&)>}; Actions = {testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >}]'
<source>:33:18: required from here
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple:1360:25: error: static assertion failed: tuple index must be in range
1360 | static_assert(__i < tuple_size<tuple<>>::value,
| ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple:1360:25: note: '(0 < ((long unsigned int)std::integral_constant<long unsigned int, 0>::value))' evaluates to false
In file included from /opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock.h:57,
from <source>:2:
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-actions.h: In instantiation of 'testing::internal::DoAllAction<Actions>::operator testing::Action<R(Args ...)>() const [with R = void; Args = {std::function<void(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&)>}; Actions = {testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >}]':
<source>:33:18: required from here
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-actions.h:1061:56: error: could not convert 'std::get<1, testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >(((const testing::internal::DoAllAction<testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >*)this)->testing::internal::DoAllAction<testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >::actions)' from 'std::__tuple_element_t<1, std::tuple<testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >' {aka 'const testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >'} to 'testing::Action<void(std::function<void(std::vector<std::__cxx11::basic_string<char> >&&)>)>'
1061 | std::get<sizeof...(Actions) - 1>(actions)};
| ^
| |
| std::__tuple_element_t<1, std::tuple<testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > > {aka const testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >}
ASM generation compiler returned: 1
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/unique_ptr.h:37,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/memory:76,
from /opt/compiler-explorer/libs/googletest/trunk/googletest/include/gtest/gtest.h:55,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple: In instantiation of 'struct std::tuple_element<0, std::tuple<> >':
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/utility:118:11: required by substitution of 'template<long unsigned int __i, class _Tp> using __tuple_element_t = typename std::tuple_element::type [with long unsigned int __i = 0; _Tp = std::tuple<>]'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple:1403:5: required by substitution of 'template<long unsigned int __i, class ... _Elements> constexpr std::__tuple_element_t<__i, std::tuple<_UTypes ...> >&& std::get(const std::tuple<_UTypes ...>&&) [with long unsigned int __i = 0; _Elements = {}]'
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-more-actions.h:515:22: required by substitution of 'template<class ... Args> decltype (testing::internal::InvokeArgument(get<0>(std::forward_as_tuple((forward<Args>)(testing::internal::InvokeArgumentAction<index, Params ...>::operator()::args)...)), declval<const std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&>())) testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::operator()<Args ...>(Args&& ...) const [with Args = {}]'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/type_traits:2466:26: required by substitution of 'template<class _Fn, class ... _Args> static std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)), std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn = testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&; _Args = {}]'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/type_traits:2477:55: required from 'struct std::__result_of_impl<false, false, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&>'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/type_traits:2482:12: [ skipping 3 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/std_function.h:344:8: required by substitution of 'template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = typename std::enable_if<_Cond::value, _Tp>::type [with _Cond = std::function<void()>::_Callable<testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__invoke_result<testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&> >; _Tp = void; _Res = void; _ArgTypes = {}]'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/std_function.h:413:9: required by substitution of 'template<class _Functor, class, class> std::function<void()>::function(_Functor) [with _Functor = testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >; <template-parameter-1-2> = void; <template-parameter-1-3> = <missing>]'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/type_traits:906:30: required from 'struct std::__is_constructible_impl<std::function<void()>, const testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&>'
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/type_traits:911:12: required from 'struct std::is_constructible<std::function<void()>, const testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&>'
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-actions.h:466:7: required by substitution of 'template<class G, class> testing::Action<void(std::function<void(std::vector<std::__cxx11::basic_string<char> >&&)>)>::Action(G&&) [with G = const testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&; <template-parameter-1-2> = <missing>]'
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-actions.h:1061:56: required from 'testing::internal::DoAllAction<Actions>::operator testing::Action<R(Args ...)>() const [with R = void; Args = {std::function<void(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&)>}; Actions = {testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >}]'
<source>:33:18: required from here
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple:1360:25: error: static assertion failed: tuple index must be in range
1360 | static_assert(__i < tuple_size<tuple<>>::value,
| ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/tuple:1360:25: note: '(0 < ((long unsigned int)std::integral_constant<long unsigned int, 0>::value))' evaluates to false
In file included from /opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock.h:57,
from <source>:2:
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-actions.h: In instantiation of 'testing::internal::DoAllAction<Actions>::operator testing::Action<R(Args ...)>() const [with R = void; Args = {std::function<void(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&&)>}; Actions = {testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >}]':
<source>:33:18: required from here
/opt/compiler-explorer/libs/googletest/trunk/googlemock/include/gmock/gmock-actions.h:1061:56: error: could not convert 'std::get<1, testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >(((const testing::internal::DoAllAction<testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >*)this)->testing::internal::DoAllAction<testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >::actions)' from 'std::__tuple_element_t<1, std::tuple<testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >' {aka 'const testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >'} to 'testing::Action<void(std::function<void(std::vector<std::__cxx11::basic_string<char> >&&)>)>'
1061 | std::get<sizeof...(Actions) - 1>(actions)};
| ^
| |
| std::__tuple_element_t<1, std::tuple<testing::PolymorphicAction<testing::internal::ReturnVoidAction>, testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > > {aka const testing::internal::InvokeArgumentAction<0, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >}
Execution build compiler returned: 1
If I remove the &&and change the argument to the function from a rvalue reference into a copy, it compiles fine. What could be happening here?
It seems it is unable to work with r-value references. The workaround:
EXPECT_CALL(myService, bar(testing::_)).WillOnce(
testing::WithArg<0>(
[] (std::function<void (std::vector<std::string>&&)> f) {
f({"hello", "world"});
}
)
Related issue has been closed for some reasons Add support for move only parameters in mocked methods.

SIGSEGV because of inheritance problem regarding base / derived classes

I have a problem with the following code, which I derived from my actual code to create a minimal example. It contains some container class, which holds a pointer to some base class. When I create an object from the derived class (which inherits from the base class) and hand it over to a container object everything seems to work fine. But when I call a method of the container object which then calls a method from the base class where I want to perform some operations of the base classes private member (which is a map) and want to return a modified map, I get a SIGSEGV. There seems to be a problem in returning something, because the print-method works fine.
#include <iostream>
#include <map>
class Base {
public:
Base() { _m_parameters.clear(); };
void parameters(const std::map <std::string, double> &m_parameters) { _m_parameters = m_parameters; };
std::map <std::string, double> get() {
std::map <std::string, double> new_map;
for(const std::pair <const std::string, double> &p : _m_parameters)
new_map.insert(std::make_pair(p.first, p.second));
return new_map;
};
void print() {
for(const std::pair <const std::string, double> &p : _m_parameters)
std::cout << p.first << ": " << p.second << "\n";
std::cout << "\n";
};
private:
std::map <std::string, double> _m_parameters;
};
class Derived : public Base {
public:
Derived() : Base() {
std::map <std::string, double> m_parameter;
for(int i = 0; i < 3; ++i) {
std::string s_name = "param_" + std::to_string(i);
auto p = (double) i;
m_parameter.insert(std::make_pair(s_name, p));
}
Base::parameters(m_parameter);
};
};
class Container {
public:
Container() { _base = nullptr; };
explicit Container(Base base) { _base = &base; };
void do_stuff() {
std::map <std::string, double> map;
_base -> print();
map = _base -> get();
for(const std::pair <const std::string, double> &p : map)
std::cout << p.first << ": " << p.second << "\n";
}
private:
Base *_base;
};
int main(int argc, char** argv) {
Derived derived = Derived();
Container container = Container(derived);
container.do_stuff();
return 0;
}
Simply running under Valgrind reveals that you're accessing memory that you freed:
==10852== Invalid read of size 8
==10852== at 0x49B05B0: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.28)
==10852== by 0x10B8FA: Base::print() (58131198.cpp:20)
==10852== by 0x10BB66: Container::do_stuff() (58131198.cpp:52)
==10852== by 0x10B327: main (58131198.cpp:65)
==10852== Address 0x4d84128 is 40 bytes inside a block of size 72 free'd
==10852== at 0x4836EAB: operator delete(void*) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==10852== by 0x10E8A5: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::deallocate(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >*, unsigned long) (new_allocator.h:128)
==10852== by 0x10E5A6: std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > > >::deallocate(std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >&, std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >*, unsigned long) (alloc_traits.h:470)
==10852== by 0x10DDF0: std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_M_put_node(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >*) (stl_tree.h:584)
==10852== by 0x10D17B: std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_M_drop_node(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >*) (stl_tree.h:651)
==10852== by 0x10C875: std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_M_erase(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >*) (stl_tree.h:1915)
==10852== by 0x10C0C1: std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::~_Rb_tree() (stl_tree.h:995)
==10852== by 0x10B701: std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, double, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::~map() (stl_map.h:300)
==10852== by 0x10B973: Base::~Base() (58131198.cpp:4)
==10852== by 0x10B31B: main (58131198.cpp:64)
==10852== Block was alloc'd at
==10852== at 0x4835DEF: operator new(unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==10852== by 0x10EAF5: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::allocate(unsigned long, void const*) (new_allocator.h:114)
==10852== by 0x10E662: std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > > >::allocate(std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >&, unsigned long) (alloc_traits.h:444)
==10852== by 0x10DEAA: std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_M_get_node() (stl_tree.h:580)
==10852== by 0x10EA7F: std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_M_create_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> const&>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> const&) (stl_tree.h:630)
==10852== by 0x10EC4E: std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_Alloc_node::operator()<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> const&>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> const&) const (stl_tree.h:548)
==10852== by 0x10E73B: std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_M_clone_node<std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_Alloc_node>(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > const*, std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_Alloc_node&) (stl_tree.h:658)
==10852== by 0x10E19F: std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_M_copy<std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_Alloc_node>(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > const*, std::_Rb_tree_node_base*, std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_Alloc_node&) (stl_tree.h:1887)
==10852== by 0x10D784: std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_M_copy<std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_Alloc_node>(std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > > const&, std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_Alloc_node&) (stl_tree.h:901)
==10852== by 0x10CE3D: std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_M_copy(std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > > const&) (stl_tree.h:912)
==10852== by 0x10C440: std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::_Rb_tree(std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > > const&) (stl_tree.h:950)
==10852== by 0x10BCCE: std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, double, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > >::map(std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, double, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, double> > > const&) (stl_map.h:205)
==10852==
There's plenty more of these use-after-free errors, so I suggest fixing them all before further debugging.
The simple fix is to pass base by reference when constructing a Container:
explicit Container(Base& base) : _base{&base} {}
With that change, it's Valgrind-clean.

Is there any way to insert a unique_ptr into a map in C++0x/gcc 4.4.7)?

I can't figure out how to do it; it's driving me nuts.
#include <iostream>
#include <memory>
#include <map>
int main()
{
std::map<std::string, std::unique_ptr<std::string>> map;
std::unique_ptr<std::string> bar(new std::string("bar"));
map["foo"] = std::move(bar);
std::cout << "foo: " << *(map["foo"]) << std::endl;
}
This compiles just fine on gcc v4.9.2:
$ g++ -std=c++0x test.cc -o test
Unfortunately, all I have available to me is gcc v4.4.7, which produces a hideous error message that I'll stick at the bottom.
I can push_back unique_ptrs into vectors just fine; I don't understand why there's an issue with map.
I've also tried using insert:
int main()
{
std::map<std::string, std::unique_ptr<std::string>> map;
std::unique_ptr<std::string> bar(new std::string("bar"));
auto pair = std::make_pair("foo", std::move(bar));
map.insert(std::move(pair));
std::cout << "foo: " << *(map["foo"]) << std::endl;
}
I can make the pair just fine, but when I try to move it into insert I get the error. It appears that it's trying to call the copy constructor for some reason, but I don't understand why, since I'm moveing it.
emplace has the same result:
int main()
{
std::map<std::string, std::unique_ptr<std::string>> map;
std::unique_ptr<std::string> bar(new std::string("bar"));
auto pair = std::make_pair("foo", std::move(bar));
map.emplace(std::move(pair));
std::cout << "foo: " << *(map["foo"]) << std::endl;
}
Both of these compile fine in g++ v4.9.2, but not in v4.4.7.
Anyone have any ideas on an alternative way to do this (in v4.4.7)?
Full error message output (from the first example):
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_algobase.h:66,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/char_traits.h:41,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ios:41,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ostream:40,
from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/iostream:40,
from test.cc:1:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/unique_ptr.h: In copy constructor 'std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::pair(const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&)':
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_pair.h:68: instantiated from 'std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/ext/new_allocator.h:111: instantiated from 'void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, _Args&& ...) [with _Args = const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, _Tp = std::_Rb_tree_node<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:394: 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 std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:881: instantiated from 'std::_Rb_tree_iterator<_Val> 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 = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:1215: instantiated from 'std::_Rb_tree_iterator<_Val> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique_(std::_Rb_tree_const_iterator<_Val>, const _Val&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_map.h:540: instantiated from 'typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::insert(typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, const std::pair<const _Key, _Tp>&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp = std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_map.h:450: instantiated from '_Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp = std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >]'
test.cc:9: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/unique_ptr.h:214: error: deleted function 'std::unique_ptr<_Tp, _Tp_Deleter>::unique_ptr(const std::unique_ptr<_Tp, _Tp_Deleter>&) [with _Tp = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp_Deleter = std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >]'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_pair.h:68: error: used here
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/map:60,
from test.cc:3:
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h: In constructor 'std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&, _Val = std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >]':
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:136: note: synthesized method 'std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::pair(const std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::default_delete<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >&)' first required here
GCC 4.4.7 does not provide full support for C++ 11 features, so it is unrealistic to expect all C++ 11 features to work properly. In this particular case, the compiler is not generating move assignment and move copy methods for you. So, when std::map attempts assignment or copy, it uses the regular default ones, which are deleted for unique_ptr.
If you just need a smart pointer, you can use shared_ptr instead.
std::map<std::string, std::shared_ptr<std::string>> map;
std::shared_ptr<std::string> bar = std::make_shared<std::string>("bar");
map["foo"] = bar;
I have looked into the issue. STL implementation for map correctly has a move constructor defined in it:
#ifdef __GXX_EXPERIMENTAL_CXX0X__
template<typename... _Args>
_Rb_tree_node(_Args&&... __args)
: _Rb_tree_node_base(),
_M_value_field(std::forward<_Args>(__args)...) { }
#endif
};
Moreover, this is called, as stated in the error output. std::pair has move constructor defined as well, but this one is not called.
I believe, std::forward and deduced type of Args is at fault:
usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../include/c++/4.4.7/bits/stl_tree.h:
In constructor ‘std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...)
[with _Args = const std::pair<..., std::unique_ptr<...> >&,
As you see, type of _Args is a const reference, which is forwarded by forward, and regular pair constructor is called.
I assume, one might fiddle with stl_tree.h to fix it - for example, by removing std::forward and just casting the arg to rvalue reference. This would not be correct, of course, but might work for specific case.

unordered_map::find doesn't work for STL types

for C++ basic types, it works
unordered_map<string, int> m;
unordered_map<string, int>::iterator itr;
string s;
itr = m.find(s);
It compiles with no problem.
However, when I try
unordered_map<set<string>, int> m;
unordered_map<set<string>, int>::iterator itr;
set<string> s;
itr = m.find(s);
The compiler complains something that I can't read. Does anyone know what is going on? Do I have to use exception here?
g++ output:
/tmp/ccdwrdVP.o: In function `std::__detail::_Hash_code_base<std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::pair<std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const, int>, std::_Select1st<std::pair<std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const, int> >, std::equal_to<std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::hash<std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_hash_code(std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) const':
test_unordermap_find.cpp:(.text._ZNKSt8__detail15_Hash_code_baseISt3setISsSt4lessISsESaISsEESt4pairIKS5_iESt10_Select1stIS8_ESt8equal_toIS5_ESt4hashIS5_ENS_18_Mod_range_hashingENS_20_Default_ranged_hashELb0EE12_M_hash_codeERS7_[std::__detail::_Hash_code_base<std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::pair<std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const, int>, std::_Select1st<std::pair<std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const, int> >, std::equal_to<std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::hash<std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>::_M_hash_code(std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) const]+0x37): undefined reference to `std::hash<std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >::operator()(std::set<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) const'
collect2: ld returned 1 exit status
std::unordered_map is implemented by means of a hash table, so it needs a hash function that can be applied to its key type. The default hash function is the std::hash template:
template < class Key,
class T,
class Hash = std::hash<Key>,
class Pred = std::equal_to<Key>,
class Alloc = std::allocator< std::pair<const Key,T> >
> class unordered_map;
However, std::hash is not defined for std::set. Therefore you need to either provide a definition of std::hash<set<string>>, or else specify your own hash function using the third template parameter of unordered_map.

Unable to iterate through template map. How to deal with this error?

I have a graph class that employs two dimension vertices using a map with another map nested inside, as such(V is my template):
map< V , map< V , int> > vertices;
Defining an iterator as such seems to be ok:
typename map< V, map< V , int>::iterator i;
However when I try to use that iterator, like this i = vertices.begin() , I get a long error that looks like this. (main.cpp 81 is where I call the method that does the iteration). Where could I look at to find what's wrong?
main.cpp:81: instantiated from here
graph.h:326: error: no match for ‘operator=’ in ‘i = ((const GraphNameSpace::Graph<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)this)->GraphNameSpace::Graph<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::vertices.std::map<_Key, _Tp, _Compare, _Alloc>::begin [with _Key = std::basic_string<char, std::char_traits<char>, std::allocator<char> >, _Tp = std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >, _Compare = std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, _Alloc = std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > > > >]()’
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_tree.h:152: note: candidates are: std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > > > >& std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > > > >::operator=(const std::_Rb_tree_iterator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > > > >&)
make: *** [main.o] Error 1
UPDATE:
At the risk of providing too much information, here is my graph class on pastebin. Right at the very bottom in the dump function is where I'm attempting to do the iteration.
The member function dump(), inside which you write i = vertices.begin(), is a const member function, which effectively makes vertices a const object, for it is a member of the class. So you need const_iterator:
typename map<V, map<V, int> >::const_iterator i;
//^^^^^ note this
It should work now. :-)