c++ - 如何放置构造 std::map<int, std::array<Class, 2>>?

标签 c++ c++11 stl

我正在学习 std::map 的就地构建我找到了使用 emplace and std::piecewise_construct, std::forward_as_tuple 的解决方案.

std::map emplace without copying value

我尝试了一个示例类,其中我删除了复制构造函数并只允许移动。 map 看起来像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;
}

但它给了我很多错误,我无法理解。 你能告诉我我做错了什么吗? 我正在使用 C++11

提前致谢!

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

最佳答案

std::forward_as_tuple(
        Class{ 10, std::string("ten") },   // here is the problem
        Class{ 20, std::string("twenty") }
    )

您正在向 std::array 构造函数传递 2 个类型为 Class 的对象,而您应该传递一个包含 2 个对象的数组

std::forward_as_tuple(
        { // !!
        Class{ 10, std::string("ten") },   // no problem here
        Class{ 20, std::string("twenty") }
         } // !!
    )

关于c++ - 如何放置构造 std::map<int, std::array<Class, 2>>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57238629/

相关文章:

C++(编译器?)释放函数中分配的内存

c++ - 当 Type = bool 时,运算符 bool() 与模板 Type() 运算符冲突

当类型 T 需要构造函数时,C++ 是否可以创建类型 T 的 std::list?

c++ - 将可变数量的参数传递给嵌入式 Python API

javascript - 如果无法分配内存,V8 会崩溃吗?这会使整个过程崩溃吗?

c++ - 如何更改 std::priority_queue top() 的值?

c++ - 使用 cmake 在多个模块中使用实用程序库(仅 header )

c++ - std::map clear() 崩溃 - 多线程

c++ - 复制空对象是否涉及访问它

c++ - 初始化类的 std::array 类型的继承成员 var 的最佳方法?