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;
}
}
Related
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.
I am working on a library which uses a struct which should not have the default constructor accessible by users of the lib.
struct Example
{
Example(int x);
private:
Example();
};
Inside the library the the default constructor is required for std::map to create new entries. The library is very careful in actually putting values everywhere where the default constructor is used.
The library uses a map to store these structs, like this:
std::map<int, Example> data;
Check HERE FOR A COMPLETE EXAMPLE in ideOne.
I would like to prevent users of the lib to be able to use the default constructor. How can I befriend std::map, std::pair and/or std::tuple to allow std::map to use this default constructor?
friend class std::map<int, Example>;
friend class std::pair<int, Example>;
do not work and i am not sure how to friend the following constructor which complains about beeing unable to access the default constructor:
// TEMPLATE CONSTRUCTOR pair::pair(tuple, tuple, sequence, sequence)
template<class _Ty1,
class _Ty2>
template<class _Tuple1,
class _Tuple2,
size_t... _Indexes1,
size_t... _Indexes2> inline
pair<_Ty1, _Ty2>::pair(_Tuple1& _Val1,
_Tuple2& _Val2,
integer_sequence<size_t, _Indexes1...>,
integer_sequence<size_t, _Indexes2...>)
: first(_STD get<_Indexes1>(_STD move(_Val1))...),
second(_STD get<_Indexes2>(_STD move(_Val2))...)
{ // construct from pair of tuples
(void) _Val1; // TRANSITION, VSO#181496
(void) _Val2;
}
Any support is much appreciated!
Edit: full error message:
In file included from /usr/include/c++/6/bits/stl_map.h:63:0,
from /usr/include/c++/6/map:61,
from prog.cpp:2:
/usr/include/c++/6/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 = {int&&}; long unsigned int ..._Indexes1 = {0ul}; _Args2 = {}; long unsigned int ..._Indexes2 = {}; _T1 = const int; _T2 = Example]’:
/usr/include/c++/6/tuple:1579:63: required from ‘std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {int&&}; _Args2 = {}; _T1 = const int; _T2 = Example]’
/usr/include/c++/6/ext/new_allocator.h:120:4: required from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const int, Example>; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const int, Example> >]’
/usr/include/c++/6/bits/alloc_traits.h:455: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, Example>; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const int, Example> >; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<std::_Rb_tree_node<std::pair<const int, Example> > >]’
/usr/include/c++/6/bits/stl_tree.h:543: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<int&&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, Example>; _KeyOfValue = std::_Select1st<std::pair<const int, Example> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, Example> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, Example> >*]’
/usr/include/c++/6/bits/stl_tree.h:560: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<int&&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, Example>; _KeyOfValue = std::_Select1st<std::pair<const int, Example> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, Example> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, Example> >*]’
/usr/include/c++/6/bits/stl_tree.h:2196: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<int&&>, std::tuple<>}; _Key = int; _Val = std::pair<const int, Example>; _KeyOfValue = std::_Select1st<std::pair<const int, Example> >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, Example> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const int, Example> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const int, Example> >]’
/usr/include/c++/6/bits/stl_map.h:502: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 = int; _Tp = Example; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, Example> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = Example; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]’
prog.cpp:17:8: required from here
/usr/include/c++/6/tuple:1590:70: error: ‘Example::Example()’ is private within this context
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
^
prog.cpp:11:2: note: declared private here
Example(){}
^~~~~~~
First, I would like to correct an important point in your post:
Inside the library the default constructor is required for std::map
You can use std::map<K,T> even if T has no default constructor. See this post. In this case you cannot use operator[] to read & write into the map. You can still do it with other methods:
read the map: V value = map.at(key);
insert into the map: map.insert(std::make_pair(key, value));.
I strongly advise to do it this way.
That being said, if you really want go down the "private constructor & friend" way, from your error message:
In instantiation of ‘std::pair<_T1, _T2>::pair(/*...*/) [with /*...*/; _T1 = const int; _T2 = Example]’
You can try to friend std::pair<const int, Example>;. As Caleth said in his answer, this might not be portable.
There is no portable solution.
Your type is not DefaultConstructible, so trying to data[5] is undefined behaviour.
For reference, I tried all the following and g++ still rejected it
struct Example
{
Example(int x) {}
private:
Example();
friend class std::map<int, Example>;
friend std::map<int, Example>::key_type;
friend std::map<int, Example>::mapped_type; // warning: class 'Example' is implicitly friends with itself
friend std::map<int, Example>::value_type;
friend std::map<int, Example>::size_type;
friend std::map<int, Example>::difference_type;
friend std::map<int, Example>::key_compare;
friend std::map<int, Example>::allocator_type;
friend std::map<int, Example>::reference;
friend std::map<int, Example>::const_reference;
friend std::map<int, Example>::pointer;
friend std::map<int, Example>::const_pointer;
friend std::map<int, Example>::iterator;
friend std::map<int, Example>::const_iterator;
friend std::map<int, Example>::reverse_iterator;
friend std::map<int, Example>::const_reverse_iterator;
friend std::map<int, Example>::node_type;
friend std::map<int, Example>::insert_return_type;
friend std::map<int, Example>::value_compare;
};
Not sure if this is normative, but my GCC accepted:
struct Example
{
Example(int x) { }
private:
friend class std::pair<int const, Example>;
Example() { }
};
Be aware that std::pair<int, Example> won't work as std::map's keys are const!
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.