Basically I have a map containing some entries. I create the entries with a custom constructor and the default constructor is deleted. In an entry I would like to update a value. This I want to achieve by a reference to the entry and then call the update/set method.
I have the following code:
#include <map>
#include <string>
class CacheEntry
{
public:
CacheEntry() = delete;
CacheEntry(const int value1)
: value1(value1)
{
}
void SetValue2(const int value2)
{
this->value2 = value2;
}
private:
const int value1;
int value2;
};
class Cache
{
public:
void SetValue2(const std::string& name, const int value2)
{
if (entries.count(name) == 0)
{
return;
}
CacheEntry& entry = entries[name];
entry.SetValue2(value2);
}
private:
std::map<std::string,CacheEntry> entries;
};
When I compile, I get the following error:
In file included from /usr/include/c++/9/bits/stl_map.h:63,
from /usr/include/c++/9/map:61,
from test.cpp:1:
/usr/include/c++/9/tuple: In instantiation of ‘std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&}; long unsigned int ..._Indexes1 = {0}; _Args2 = {}; long unsigned int ..._Indexes2 = {}; _T1 = const std::__cxx11::basic_string<char>; _T2 = CacheEntry]’:
/usr/include/c++/9/tuple:1663:63: required from ‘std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&}; _Args2 = {}; _T1 = const std::__cxx11::basic_string<char>; _T2 = CacheEntry]’
/usr/include/c++/9/ext/new_allocator.h:147:4: required from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const std::__cxx11::basic_string<char>, CacheEntry>; _Args = {const std::piecewise_construct_t&, std::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >]’
/usr/include/c++/9/bits/alloc_traits.h:484:4: required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::pair<const std::__cxx11::basic_string<char>, CacheEntry>; _Args = {const std::piecewise_construct_t&, std::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> > >]’
/usr/include/c++/9/bits/stl_tree.h:614:32: required from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_construct_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>, std::tuple<>}; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, CacheEntry>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >*]’
/usr/include/c++/9/bits/stl_tree.h:631:4: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>, std::tuple<>}; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, CacheEntry>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >*]’
/usr/include/c++/9/bits/stl_tree.h:2455:13: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&>, std::tuple<>}; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, CacheEntry>; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >]’
/usr/include/c++/9/bits/stl_map.h:499:8: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::__cxx11::basic_string<char>; _Tp = CacheEntry; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, CacheEntry> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = CacheEntry; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::__cxx11::basic_string<char>]’
test.cpp:33:36: required from here
/usr/include/c++/9/tuple:1674:70: error: use of deleted function ‘CacheEntry::CacheEntry()’
1674 | second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
| ^
test.cpp:7:3: note: declared here
7 | CacheEntry() = delete;
| ^~~~~~~~~~
Why does the compiler create a new object at CacheEntry& entry = entries[name];? I expect a reference to the already existing object in the map.
I know I can remove the CacheEntry() = delete;, but this is not what I want.
Why does the compiler create a new object at CacheEntry& entry = entries[name];?
map::operator[] creates a new default-constructed entry if the specified key doesn't exist. Even though you are using map::count() to ensure that no new entry will actually be created, the implementation code behind operator[] still has to compile properly. That means if you want to use operator[], the map's entries MUST have a valid default constructor.
Otherwise, don't use operator[] at all, use map::find() instead, eg:
void SetValue2(const std::string& name, const int value2)
{
auto iter = entries.find(name);
if (iter != entries.end())
iter->second.SetValue2(value2);
}
I expect a reference to the already existing object in the map.
Correct - at runtime. But at compile-time, the compiler has no way to know that an object will already exist.
Related
I hate copypasting the whole log here but I can't understand what these errors mean...
I understand some of them have to do with the way I'm using the unique_ptr, but since my IDE doesn't directly point out the incriminated lines I don't know what to do.
In file included from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/i686-w64-mingw32/bits/c++allocator.h:33,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/allocator.h:46,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/string:41,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ios:42,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ostream:38,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/iostream:39,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Column.h:8,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.h:8,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.cpp:5:
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ext/new_allocator.h: In instantiation of 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _Args = {const std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<Column, std::default_delete<Column> > >&}; _Tp = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >]':
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/alloc_traits.h:475:4: required from 'static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _Args = {const std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<Column, std::default_delete<Column> > >&}; _Tp = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > > >]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:637:32: required from 'void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_construct_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, _Args&& ...) [with _Args = {const std::pair<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<Column, std::default_delete<Column> > >&}; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:506:3: required from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Reuse_or_alloc_node::operator()(_Arg&&) [with _Arg = const std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >&; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:677:33: required from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_clone_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type, _NodeGen&) [with _NodeGen = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > > >::_Reuse_or_alloc_node; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type = const std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:1834:13: required from 'std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_copy(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, _NodeGen&) [with _NodeGen = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > > >::_Reuse_or_alloc_node; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Const_Link_type = const std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr = std::_Rb_tree_node_base*]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:891:15: 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 _NodeGen = std::_Rb_tree<std::__cxx11::basic_string<char>, std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >, std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >, std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > > >::_Reuse_or_alloc_node; _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >*]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_tree.h:1742:16: required from 'std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::operator=(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&) [with _Key = std::__cxx11::basic_string<char>; _Val = std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> >; _KeyOfValue = std::_Select1st<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >; _Compare = std::less<std::__cxx11::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::__cxx11::basic_string<char>, std::unique_ptr<Column> > >]'
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_map.h:100:11: required from here
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ext/new_allocator.h:136:4: error: use of deleted function 'constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const std::__cxx11::basic_string<char>; _T2 = std::unique_ptr<Column>]'
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_algobase.h:64,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/char_traits.h:39,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ios:40,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/ostream:38,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/iostream:39,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Column.h:8,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.h:8,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.cpp:5:
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_pair.h:292:17: note: 'constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const std::__cxx11::basic_string<char>; _T2 = std::unique_ptr<Column>]' is implicitly deleted because the default definition would be ill-formed:
constexpr pair(const pair&) = default;
^~~~
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/stl_pair.h:292:17: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Column; _Dp = std::default_delete<Column>]'
In file included from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/locale_conv.h:41,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/locale:43,
from C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/iomanip:43,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Date.h:12,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\DateColumn.h:8,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.h:14,
from C:\Users\Andrea\CLionProjects\Final_Project_2nd\Tab.cpp:5:
C:/PROGRA~2/MINGW-~1/I686-8~1.0-P/mingw32/lib/gcc/i686-w64-mingw32/8.1.0/include/c++/bits/unique_ptr.h:394:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
^~~~~~~~~~
mingw32-make.exe[3]: *** [CMakeFiles\Final_Project_2nd.dir\build.make:179: CMakeFiles/Final_Project_2nd.dir/Tab.cpp.obj] Error 1
mingw32-make.exe[3]: *** Waiting for unfinished jobs....
mingw32-make.exe[2]: *** [CMakeFiles\Makefile2:75: CMakeFiles/Final_Project_2nd.dir/all] Error 2
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:82: CMakeFiles/Final_Project_2nd.dir/rule] Error 2
mingw32-make.exe: *** [Makefile:117: Final_Project_2nd] Error 2
This is Tab.h:
class Tab {
public:
Tab();
~Tab();
void addColumn(string name, string type);
void addRecord(string column);
void operator=(const Tab& to_assign);
private:
map<string, unique_ptr<Column>> _columns;
int _primary_key;
};
And these are two methods:
void Tab::addColumn(string name, string type) {
// I switch all the different types and create a new element on the columns map
// depending on what is the result
switch(Type2Int(type)) {
case OptionInt:
_columns[name].reset(new IntColumn());
break;
case OptionFloat:
_columns[name].reset(new FloatColumn());
break;
case OptionChar:
_columns[name].reset(new CharColumn());
break;
case OptionText:
_columns[name].reset(new TextColumn());
break;
case OptionTime:
_columns[name].reset(new TimeColumn());
break;
case OptionDate:
_columns[name].reset(new DateColumn());
break;
}
}
void Tab::operator=(const Tab &to_assign) {
_columns = to_assign._columns;
}
ColumnImpl class:
template <typename T> class ColumnImpl : public Column {
public:
ColumnImpl();
ColumnImpl(const T& to_set);
vector<T> const& getData() const { return _data; }
void addElem(const T& elem_to_add);
void operator=(const ColumnImpl& to_assign);
protected:
vector<T> _data;
};
And this is a supsect method:
template<typename T>
void ColumnImpl<T>::operator=(const ColumnImpl &to_assign) {
_data = to_assign._data;
}
Database.h:
class Database {
public:
Database();
~Database();
void createNewTable(string name);
void addColumnToTab(string tab_name, string col_name, string type);
private:
map<string, Tab> _tables;
};
These are the only two methods I've implemented:
void Database::createNewTable(string name) {
_tables[name] = Tab();
}
void Database::addColumnToTab(string tab_name, string col_name, string type) {
const auto & it_target_tab = _tables.find(tab_name);
it_target_tab->second.addColumn(col_name, type);
}
I have this map map<int, PageTableEntry>> processmapram where the key is an integer and the value is the class object. This is how values are inserted to it.
for(i=0;i<lenDataSegment;i+=PG_SIZE)
{
int ramloc = getFreeSpaceRAM();
if(ramloc == -1)
{
int swaploc = getFreeSwapSpace();
bitmapSWAP[swaploc/PG_SIZE] = 1;
PageTableEntry pte(swaploc, 1, 0);
processmapram.insert({i, pte}); \\ insert values to map
strncpy(pSWap+swaploc, DataSeg+i, PG_SIZE);
}
else
{
bitmapRAM[ramloc/PG_SIZE] = 1;
PageTableEntry pte(ramloc, 0, 1);
processmapram.insert({i, pte}); \\ insert values to map
strncpy(pRAM+ramloc, DataSeg+i, PG_SIZE);
}
}
The PageTableEntry structure is defined as
typedef struct PageTableEntry {
int phyadd;
int flagswap;
int flagram;
PageTableEntry(int phyadd, int flagswap, int flagram)
{
this->phyadd = phyadd;
this->flagswap = flagswap;
this->flagram = flagram;
}
} PageTableEntry;
Now when I am accessing the same in another function I am getting an error :
int Process::readAddress(int virtualAddr, int lenToRead, char *buf)
{
cout<<processmapram[virtualAddr].phyadd;
}
or like this
PageTableEntry pte(-1,0,0);
pte = mymap[virtualAddr];
cout<<pte.phyadd;
Error :
In file included from /usr/include/c++/7/functional:54:0,
from /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h:71,
from Process.h:1,
from ProcessManager.h:1,
from Process.cpp:3:
/usr/include/c++/7/tuple: In instantiation of ‘std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {const int&}; long unsigned int ..._Indexes1 = {0}; _Args2 = {}; long unsigned int ..._Indexes2 = {}; _T1 = const int; _T2 = PageTableEntry]’:
/usr/include/c++/7/tuple:1641:63: required from ‘std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {const int&}; _Args2 = {}; _T1 = const int; _T2 = PageTableEntry]’
/usr/include/c++/7/ext/new_allocator.h:136:4: required from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const int, PageTableEntry>; _Args = {const std::piecewise_construct_t&, std::tuple<const int&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const int, PageTableEntry> >]’
/usr/include/c++/7/bits/alloc_traits.h:475:4: required from ‘static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::pair<const int, PageTableEntry>; _Args = {const std::piecewise_construct_t&, std::tuple<const int&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const int, PageTableEntry> >; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<std::_Rb_tree_node<std::pair<const int, PageTableEntry> > >]’
/usr/include/c++/7/bits/stl_tree.h:626:32: required from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_construct_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const int&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, PageTableEntry>; _KeyOfValue = std::_Select1st<std::pair<const int, PageTableEntry> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, PageTableEntry> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, PageTableEntry> >*]’
/usr/include/c++/7/bits/stl_tree.h:643:21: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const int&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, PageTableEntry>; _KeyOfValue = std::_Select1st<std::pair<const int, PageTableEntry> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, PageTableEntry> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, PageTableEntry> >*]’
/usr/include/c++/7/bits/stl_tree.h:2398:33: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const int&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, PageTableEntry>; _KeyOfValue = std::_Select1st<std::pair<const int, PageTableEntry> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, PageTableEntry> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, PageTableEntry> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const int, PageTableEntry> >]’
/usr/include/c++/7/bits/stl_map.h:493:8: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = int; _Tp = PageTableEntry; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, PageTableEntry> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = PageTableEntry; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]’
Process.cpp:19:26: required from here
/usr/include/c++/7/tuple:1652:70: error: no matching function for call to ‘PageTableEntry::PageTableEntry()’
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
^
In file included from ProcessManager.h:1:0,
from Process.cpp:3:
Process.h:80:2: note: candidate: PageTableEntry::PageTableEntry(int, int, int)
PageTableEntry(int phyadd, int flagswap, int flagram)
^~~~~~~~~~~~~~
Process.h:80:2: note: candidate expects 3 arguments, 0 provided
Process.h:76:16: note: candidate: constexpr PageTableEntry::PageTableEntry(const PageTableEntry&)
typedef struct PageTableEntry {
^~~~~~~~~~~~~~
Process.h:76:16: note: candidate expects 1 argument, 0 provided
Process.h:76:16: note: candidate: constexpr PageTableEntry::PageTableEntry(PageTableEntry&&)
Process.h:76:16: note: candidate expects 1 argument, 0 provided
Note : The example posted here is the minimal code for a large project. I have just posted minimal reproducible example here.
I think in your Process::readAddress function you want to print an existing entry.
So you need to make sure that required entry is found in the map, rather than silently creating a new one for each virtualAddr - that is what operator[] will do and for what it needs default ctor, as others mentioned in the comments. You can use std::map::find
int Process::readAddress(int virtualAddr, int lenToRead, char *buf)
{
auto it = processmapram.find(virtualAddr);
if(it != processmapram.end())
{
cout << it->second.phyadd;
}
}
What is the correct way to call the print() method when accessing prime as a value of an std::map:
#include <iostream>
#include <map>
using namespace std;
class Prime {
private:
int n;
public:
Prime(int n): n(n) {}
Prime(const Prime &P) {
n = P.n;
}
void print() {
cout << "value: " << n << endl;
}
};
int main() {
Prime prime(5);
map<string, Prime> myMap;
myMap.emplace("five", prime);
// this line appears to be failing
myMap["five"].print();
return 1;
}
When I run this code $ g++ -std=c++11 main.cpp && ./a.out:
In file included from /usr/include/c++/4.8/bits/stl_map.h:63:0,
from /usr/include/c++/4.8/map:61,
from main.cpp:4:
/usr/include/c++/4.8/tuple: In instantiation of ‘std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&}; long unsigned int ..._Indexes1 = {0ul}; _Args2 = {}; long unsigned int ..._Indexes2 = {}; _T1 = const std::basic_string<char>; _T2 = Prime]’:
/usr/include/c++/4.8/tuple:1079:63: required from ‘std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&}; _Args2 = {}; _T1 = const std::basic_string<char>; _T2 = Prime]’
/usr/include/c++/4.8/bits/stl_tree.h:140:49: required from ‘std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Val = std::pair<const std::basic_string<char>, Prime>]’
/usr/include/c++/4.8/ext/new_allocator.h:120:4: required from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::_Rb_tree_node<std::pair<const std::basic_string<char>, Prime> >; _Args = {const std::piecewise_construct_t&, std::tuple<std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const std::basic_string<char>, Prime> >]’
/usr/include/c++/4.8/bits/alloc_traits.h:254:4: required from ‘static typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::_Rb_tree_node<std::pair<const std::basic_string<char>, Prime> >; _Args = {const std::piecewise_construct_t&, std::tuple<std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Alloc = std::allocator<std::_Rb_tree_node<std::pair<const std::basic_string<char>, Prime> > >; typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type = void]’
/usr/include/c++/4.8/bits/alloc_traits.h:393:57: required from ‘static decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::_Rb_tree_node<std::pair<const std::basic_string<char>, Prime> >; _Args = {const std::piecewise_construct_t&, std::tuple<std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Alloc = std::allocator<std::_Rb_tree_node<std::pair<const std::basic_string<char>, Prime> > >; decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = <type error>]’
/usr/include/c++/4.8/bits/stl_tree.h:408:36: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Key = std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, Prime>; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, Prime> >; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, Prime> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::basic_string<char>, Prime> >*]’
/usr/include/c++/4.8/bits/stl_tree.h:1669:64: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Key = std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, Prime>; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, Prime> >; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, Prime> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, Prime> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, Prime> >]’
/usr/include/c++/4.8/bits/stl_map.h:484:8: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::basic_string<char>; _Tp = Prime; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, Prime> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = Prime; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::basic_string<char>]’
main.cpp:31:15: required from here
/usr/include/c++/4.8/tuple:1090:70: error: no matching function for call to ‘Prime::Prime()’
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
^
/usr/include/c++/4.8/tuple:1090:70: note: candidates are:
main.cpp:15:3: note: Prime::Prime(const Prime&)
Prime(const Prime &P) {
^
main.cpp:15:3: note: candidate expects 1 argument, 0 provided
main.cpp:13:3: note: Prime::Prime(int)
Prime(int n): n(n) {}
^
main.cpp:13:3: note: candidate expects 1 argument, 0 provided
Writing Prime(int n = 0): n(n) {} is your fix.
Even if you are using emplace, the Prime class is required by the C++ standard to have a default constructor, which yours currently doesn't.
I have a big class (call it Collection) and a small class (Item).
Upon initialization of a Collection object it creates a vector of maps to the small objects. The overall structure looks like:
vector<map<int,Item>> storage;
Specifically it looks like:
vector<map<int,Node>> layers;
So when I call a method of Collection to access Item, i.e.
layers[vector_index][map_index].some_method();
it forces Item to be reinitialized. Here's the specific code:
void NN::set_hidden_weights(int hidden_layer_num,int node_index,map<int,double> new_weights){
layers[hidden_layer_num][node_index].set_weights(new_weights); //updates weights
}
What I mean is that I get the following error from my compiler:
g++ -o tests.exe tests.cpp ../src/neural_network.cpp -std=c++11
In file included from /usr/include/c++/4.8/bits/stl_map.h:63:0,
from /usr/include/c++/4.8/map:61,
from ../src/neural_network.cpp:8:
/usr/include/c++/4.8/tuple: In instantiation of ‘std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {const int&}; long unsigned int ..._Indexes1 = {0ul}; _Args2 = {}; long unsigned int ..._Indexes2 = {}; _T1 = const int; _T2 = Node]’:
/usr/include/c++/4.8/tuple:1079:63: required from ‘std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {const int&}; _Args2 = {}; _T1 = const int; _T2 = Node]’
/usr/include/c++/4.8/bits/stl_tree.h:140:49: required from ‘std::_Rb_tree_node<_Val>::_Rb_tree_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const int&>, std::tuple<>}; _Val = std::pair<const int, Node>]’
/usr/include/c++/4.8/ext/new_allocator.h:120:4: required from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::_Rb_tree_node<std::pair<const int, Node> >; _Args = {const std::piecewise_construct_t&, std::tuple<const int&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const int, Node> >]’
/usr/include/c++/4.8/bits/alloc_traits.h:254:4: required from ‘static typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::_Rb_tree_node<std::pair<const int, Node> >; _Args = {const std::piecewise_construct_t&, std::tuple<const int&>, std::tuple<>}; _Alloc = std::allocator<std::_Rb_tree_node<std::pair<const int, Node> > >; typename std::enable_if<std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::value, void>::type = void]’
/usr/include/c++/4.8/bits/alloc_traits.h:393:57: required from ‘static decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::_Rb_tree_node<std::pair<const int, Node> >; _Args = {const std::piecewise_construct_t&, std::tuple<const int&>, std::tuple<>}; _Alloc = std::allocator<std::_Rb_tree_node<std::pair<const int, Node> > >; decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = <type error>]’
/usr/include/c++/4.8/bits/stl_tree.h:408:36: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const int&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, Node>; _KeyOfValue = std::_Select1st<std::pair<const int, Node> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, Node> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, Node> >*]’
/usr/include/c++/4.8/bits/stl_tree.h:1669:64: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const int&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, Node>; _KeyOfValue = std::_Select1st<std::pair<const int, Node> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, Node> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, Node> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const int, Node> >]’
/usr/include/c++/4.8/bits/stl_map.h:465:8: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = int; _Tp = Node; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, Node> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = Node; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]’
../src/neural_network.cpp:135:27: required from here
/usr/include/c++/4.8/tuple:1090:70: error: no matching function for call to ‘Node::Node()’
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
^
/usr/include/c++/4.8/tuple:1090:70: note: candidates are:
../src/neural_network.cpp:12:1: note: Node::Node(int, std::vector<int>)
Node::Node(int node_index, vector<int> input_indices){
^
../src/neural_network.cpp:12:1: note: candidate expects 2 arguments, 0 provided
In file included from ../src/neural_network.cpp:9:0:
../src/neural_network.hpp:12:7: note: Node::Node(const Node&)
class Node{
^
../src/neural_network.hpp:12:7: note: candidate expects 1 argument, 0 provided
../src/neural_network.hpp:12:7: note: Node::Node(Node&&)
../src/neural_network.hpp:12:7: note: candidate expects 1 argument, 0 provided
I don't have a default constructor for my Item class nor a copy constructor, and at any rate what I really want to do is manipulate the Item itself, not a copy of it. Does anyone have any recommendations on how to proceed? I'm really confused why I'm getting these initialization errors when the object Item is already created.
Invocation of indexing operator on map layers[hidden_layer_num][node_index] causes a new map to be constructed (if it wasn't there yet) with node_index as key and default constructed value. You should use map::find() to access already present items.
I'm trying to implement a class that represents a connection to a file, hence it should be a non-copyable class. Also, since a filename is required to create the object, I'd like to remove the default constructor.
Here is a simplified definition of such a class :
class Elem
{
public:
Elem() = delete;
Elem(string name) : file(new ifstream(name,ios::in)) {}
Elem(const Elem&) = delete;
Elem& operator=(const Elem& o) = delete;
Elem& operator=(Elem && o)
{
swap(o.file,file);
o.file = nullptr;
}
Elem(Elem &&o) : file(nullptr)
{
swap(file,o.file);
}
~Elem()
{
if(file!=nullptr){
file->close();
delete file;
}
}
protected:
ifstream* file;
};
However, when I try to store such objects in a standard map, the code fails to compile :
int main(){
map<string,Elem> m;
m["file1"] = move(Elem("file1"));
cout<<m.size()<<endl;
return 0;
}
I get the following errors (gcc 4.9.1) :
In file included from /usr/include/c++/4.9.1/bits/stl_map.h:63:0,
from /usr/include/c++/4.9.1/map:61,
from test.cpp:1:
/usr/include/c++/4.9.1/tuple: In instantiation of ‘std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&}; unsigned int ..._Indexes1 = {0u}; _Args2 = {}; unsigned int ..._Indexes2 = {}; _T1 = const std::basic_string<char>; _T2 = Elem]’
/usr/include/c++/4.9.1/tuple:1088:63: required from ‘std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&}; _Args2 = {}; _T1 = const std::basic_string<char>; _T2 = Elem]’
/usr/include/c++/4.9.1/ext/new_allocator.h:120:4: required from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const std::basic_string<char>, Elem>; _Args = {const std::piecewise_construct_t&, std::tuple<std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const std::basic_string<char>, Elem> >]’
/usr/include/c++/4.9.1/bits/alloc_traits.h:253:4: required from ‘static std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> std::allocator_traits<_Alloc>::_S_construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::pair<const std::basic_string<char>, Elem>; _Args = {const std::piecewise_construct_t&, std::tuple<std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Alloc = std::allocator<std::_Rb_tree_node<std::pair<const std::basic_string<char>, Elem> > >; std::_Require<typename std::allocator_traits<_Alloc>::__construct_helper<_Tp, _Args>::type> = void]’
/usr/include/c++/4.9.1/bits/alloc_traits.h:399:57: required from ‘static decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) std::allocator_traits<_Alloc>::construct(_Alloc&, _Tp*, _Args&& ...) [with _Tp = std::pair<const std::basic_string<char>, Elem>; _Args = {const std::piecewise_construct_t&, std::tuple<std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Alloc = std::allocator<std::_Rb_tree_node<std::pair<const std::basic_string<char>, Elem> > >; decltype (_S_construct(__a, __p, (forward<_Args>)(std::allocator_traits::construct::__args)...)) = <type error>]’
/usr/include/c++/4.9.1/bits/stl_tree.h:423:42: required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Key = std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, Elem>; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, Elem> >; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, Elem> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const std::basic_string<char>, Elem> >*]’
/usr/include/c++/4.9.1/bits/stl_tree.h:1790:64: required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<std::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>, std::tuple<>}; _Key = std::basic_string<char>; _Val = std::pair<const std::basic_string<char>, Elem>; _KeyOfValue = std::_Select1st<std::pair<const std::basic_string<char>, Elem> >; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, Elem> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::basic_string<char>, Elem> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const std::basic_string<char>, Elem> >]’
/usr/include/c++/4.9.1/bits/stl_map.h:519:8: required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::basic_string<char>; _Tp = Elem; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, Elem> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = Elem; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::basic_string<char>]’
test.cpp:41:14: required from here
/usr/include/c++/4.9.1/tuple:1099:70: erreur: use of deleted function ‘Elem::Elem()’
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
^
test.cpp:11:5: note: declared here
Elem() = delete;
Any clues about how this could be achieved ? Are their other design flaws in my structure ?
Thanks in advance
What you're doing is:
map<string,Elem> m;
m["file1"] = // this default-constructs an Elem
// and returns a reference to it in the correct spot
move(Elem("file1")); // and THEN move-assigns it
What you need to do:
map<string, Elem> m;
m.emplace("file1", Elem("file1"));
or
m.insert(std::make_pair("file1", Elem("file1"));
or
m.emplace(std::piecewise_construct,
std::forward_as_tuple("file1"),
std::forward_as_tuple("file1"));
As for your design, the comments point out the issue that you're potentially leaking a stream. But this is actually a really easy fix. What you are expressing is unique ownership over a file, where that ownership is transferable. There's a type for that: unique_ptr!
class Elem {
std::unique_ptr<ifstream> file;
public:
Elem() = delete;
Elem(string name) : file(new ifstream(name,ios::in)) {}
Elem(Elem&& ) = default;
Elem& operator=(Elem&& ) = default;
~Elem() = default;
Elem(const Elem&) = delete;
Elem& operator=(const Elem&) = delete;
};
Using unique_ptr makes those default/delete lines not even necessary (except the default constructor one - since that's a requirement you're enforcing), which is even better (see Rule of Zero). I'm just illustrating them for clarity.