I was learning about the in-place construction of std::map
and I found a solution using emplace and std::piecewise_construct, std::forward_as_tuple
.
std::map emplace without copying value
I tried it with an example class in which I deleted the copy constructor and allowed only move. The map looks like std::map<int, std::array<Class, 2>> myMap;
.
#include <iostream>
#include <string>
#include <map>
#include <tuple>
#include <array>
class Class
{
int m_var;
std::string m_str;
public:
Class(int var, const std::string& str) : m_var(var), m_str(str)
{
std::cout << "Cont'r called...\n";
}
Class(const Class&) = delete;
Class& operator=(const Class&) = delete;
Class(Class&& other) :m_var(std::move(other.m_var)), m_str(std::move(other.m_str))
{
std::cout << "Move called...\n";
}
Class& operator=(Class&& other)
{
this->m_var = std::move(other.m_var);
this->m_str = std::move(other.m_str);
std::cout << "Move= called...\n";
return *this;
}
};
using Value = std::array<Class, 2>;
int main()
{
std::map<int, Value> myMap;
// create in place the objects
myMap.emplace(
std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple(
Class{ 10, std::string("ten") }, // here is the problem
Class{ 20, std::string("twenty") }
)
);
return 0;
}
But it gave me a lot of error, which I couldn't understand. Could you please tell me what I did wrong here? I'm using C++11.
Thanks in advance!
In file included from /opt/wandbox/gcc-6.3.0/include/c++/6.3.0/bits/stl_map.h:63:0,
from /opt/wandbox/gcc-6.3.0/include/c++/6.3.0/map:61,
from prog.cc:3:
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/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 = {Class&&, Class&&}; long unsigned int ..._Indexes2 = {0ul, 1ul}; _T1 = const int; _T2 = std::array<Class, 2ul>]':
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/tuple:1575:63: required from 'std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {int&&}; _Args2 = {Class&&, Class&&}; _T1 = const int; _T2 = std::array<Class, 2ul>]'
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/ext/new_allocator.h:120:4: required from 'void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const int, std::array<Class, 2ul> >; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<Class&&, Class&&>}; _Tp = std::_Rb_tree_node<std::pair<const int, std::array<Class, 2ul> > >]'
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/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, std::array<Class, 2ul> >; _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<Class&&, Class&&>}; _Tp = std::_Rb_tree_node<std::pair<const int, std::array<Class, 2ul> > >; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<std::_Rb_tree_node<std::pair<const int, std::array<Class, 2ul> > > >]'
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/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<Class&&, Class&&>}; _Key = int; _Val = std::pair<const int, std::array<Class, 2ul> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::array<Class, 2ul> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::array<Class, 2ul> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, std::array<Class, 2ul> > >*]'
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/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<Class&&, Class&&>}; _Key = int; _Val = std::pair<const int, std::array<Class, 2ul> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::array<Class, 2ul> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::array<Class, 2ul> > >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const int, std::array<Class, 2ul> > >*]'
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/bits/stl_tree.h:2149:64: required from 'std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_unique(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<Class&&, Class&&>}; _Key = int; _Val = std::pair<const int, std::array<Class, 2ul> >; _KeyOfValue = std::_Select1st<std::pair<const int, std::array<Class, 2ul> > >; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::array<Class, 2ul> > >]'
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/bits/stl_map.h:559:64: required from 'std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::emplace(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<int&&>, std::tuple<Class&&, Class&&>}; _Key = int; _Tp = std::array<Class, 2ul>; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::array<Class, 2ul> > >; typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<std::pair<const _Key, _Tp> >::other>::iterator = std::_Rb_tree_iterator<std::pair<const int, std::array<Class, 2ul> > >]'
prog.cc:43:2: required from here
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/tuple:1586:70: error: no matching function for call to 'std::array<Class, 2ul>::array(Class, Class)'
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
^
In file included from /opt/wandbox/gcc-6.3.0/include/c++/6.3.0/tuple:39:0,
from /opt/wandbox/gcc-6.3.0/include/c++/6.3.0/bits/stl_map.h:63,
from /opt/wandbox/gcc-6.3.0/include/c++/6.3.0/map:61,
from prog.cc:3:
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/array:90:12: note: candidate: std::array<Class, 2ul>::array(std::array<Class, 2ul>&&)
struct array
^~~~~
/opt/wandbox/gcc-6.3.0/include/c++/6.3.0/array:90:12: note: candidate expects 1 argument, 2 provided
Aucun commentaire:
Enregistrer un commentaire