【问题标题】:Create a std::vector of std::vectors of class without copy constructor创建一个 std::vector 的 std::vector 类的没有复制构造函数
【发布时间】:2020-10-05 22:16:36
【问题描述】:

我想创建一个std::vector<std::vector<LibraryClass>>,其中LibraryClass 对我来说不可用于修改,并且没有复制构造函数。

对于std::vector<LibraryClass>,以下代码编译:

#include <vector>

class LibraryClass {
    public:
        LibraryClass() {};
        LibraryClass(const LibraryClass&) = delete;     
};

class MainClass {
    public:
        MainClass(int); 
        std::vector<LibraryClass> collection;
};

MainClass::MainClass(int nx)
: collection( nx ) { 
}

int main() {        
    MainClass main_class(3);    
}

但是使用std::vector&lt;std::vector&lt;LibraryClass&gt;&gt;,它不会(使用已删除的函数 - 复制构造函数):

#include <vector>

class LibraryClass {
    public:
        LibraryClass() {};
        LibraryClass(const LibraryClass&) = delete;     
};

class MainClass {
    public:
        MainClass(int, int);    
        std::vector<std::vector<LibraryClass>> collection;
};

MainClass::MainClass(int nx, int ny)
: collection( nx, std::vector<LibraryClass>(ny) ) { 
}

int main() {        
    MainClass main_class(3, 4); 
}

我能做些什么来实现这一目标?

提前谢谢你。

编辑:使用g++ -o test_vec_of_ves test_vec_of_vecs.cpp 编译后,确切的错误是:


In file included from /usr/include/c++/7/vector:62:0,
                 from test_vec_of_vecs.cpp:1:
/usr/include/c++/7/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = LibraryClass; _Args = {const LibraryClass&}]’:
/usr/include/c++/7/bits/stl_uninitialized.h:83:18:   required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const LibraryClass*, std::vector<LibraryClass> >; _ForwardIterator = LibraryClass*; bool _TrivialValueTypes = false]’
/usr/include/c++/7/bits/stl_uninitialized.h:134:15:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const LibraryClass*, std::vector<LibraryClass> >; _ForwardIterator = LibraryClass*]’
/usr/include/c++/7/bits/stl_uninitialized.h:289:37:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = __gnu_cxx::__normal_iterator<const LibraryClass*, std::vector<LibraryClass> >; _ForwardIterator = LibraryClass*; _Tp = LibraryClass]’
/usr/include/c++/7/bits/stl_vector.h:331:31:   required from ‘std::vector<_Tp, _Alloc>::vector(const std::vector<_Tp, _Alloc>&) [with _Tp = LibraryClass; _Alloc = std::allocator<LibraryClass>]’
/usr/include/c++/7/bits/stl_construct.h:75:7:   required from ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = std::vector<LibraryClass>; _Args = {const std::vector<LibraryClass, std::allocator<LibraryClass> >&}]’
/usr/include/c++/7/bits/stl_uninitialized.h:210:18:   required from ‘static _ForwardIterator std::__uninitialized_fill_n<_TrivialValueType>::__uninit_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = std::vector<LibraryClass>*; _Size = long unsigned int; _Tp = std::vector<LibraryClass>; bool _TrivialValueType = false]’
/usr/include/c++/7/bits/stl_uninitialized.h:255:17:   required from ‘_ForwardIterator std::uninitialized_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = std::vector<LibraryClass>*; _Size = long unsigned int; _Tp = std::vector<LibraryClass>]’
/usr/include/c++/7/bits/stl_uninitialized.h:366:39:   required from ‘_ForwardIterator std::__uninitialized_fill_n_a(_ForwardIterator, _Size, const _Tp&, std::allocator<_Tp2>&) [with _ForwardIterator = std::vector<LibraryClass>*; _Size = long unsigned int; _Tp = std::vector<LibraryClass>; _Tp2 = std::vector<LibraryClass>]’
/usr/include/c++/7/bits/stl_vector.h:1342:33:   required from ‘void std::vector<_Tp, _Alloc>::_M_fill_initialize(std::vector<_Tp, _Alloc>::size_type, const value_type&) [with _Tp = std::vector<LibraryClass>; _Alloc = std::allocator<std::vector<LibraryClass> >; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = std::vector<LibraryClass>]’
/usr/include/c++/7/bits/stl_vector.h:298:27:   required from ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = std::vector<LibraryClass>; _Alloc = std::allocator<std::vector<LibraryClass> >; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = std::vector<LibraryClass>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::vector<LibraryClass> >]’
test_vec_of_vecs.cpp:17:49:   required from here
/usr/include/c++/7/bits/stl_construct.h:75:7: error: use of deleted function ‘LibraryClass::LibraryClass(const LibraryClass&)’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test_vec_of_vecs.cpp:6:3: note: declared here
   LibraryClass(const LibraryClass&) = delete;
   ^~~~~~~~~~~~

【问题讨论】:

  • 请引用你得到的确切错误和它所暗示的行,并说明是哪个编译器/设置给出的。我改为使用g++ - include/c++/9.3.0/bits/stl_uninitialized.h:127:72: error: static assertion failed: result type must be constructible from value type of input range 得到这个。如果注释掉复制 ctor 的 delete,它确实会消失。
  • 这能回答你的问题吗? Insert into vector having objects without copy constructor 如果是这样,那么我认为就是这样,如果您无法添加复制/移动 ctor,也许您需要存储 vectorsunique_ptrs 来代替。
  • @underscore_d:不幸的是,我无法修改 LibraryClass(我把它放在那里是为了做一个最小的工作示例)。因此,我也无法添加移动构造函数。
  • 那么我认为您需要将其存储为unique_ptr,并通过使用std::make_unique&lt;LibraryClass&gt;() 的N 个元素构造来重新初始化默认构造元素的向量。
  • 好吧,我想通了。我花了一段时间,但它似乎工作。我正在添加解决方案作为问题的答案。感谢您的帮助!

标签: c++ stdvector copy-constructor


【解决方案1】:

根据 underscore_d 的建议,这里有一个似乎可以工作的版本(包括一些显示某事已完成的功能)。

#include <vector>
#include <iostream>
#include <memory>

class LibraryClass {
    public:
        LibraryClass() {};
        LibraryClass(const LibraryClass&) = delete;
        void init(int aa, int bb) { a = aa; b = bb; };
        void report() { std::cout << "I am " << a << " / " << b << std::endl; };        
    private: 
        int a, b;               
};

class MainClass {
    public:
        MainClass(int, int);                    
        void init();
        void report();              
        std::vector<std::vector<std::unique_ptr<LibraryClass>>> collection;
};

MainClass::MainClass(int nx, int ny) { 
    collection.resize(nx);
    for (int i=0; i<nx; ++i) {      
        collection[i].resize(ny);               
        for (int j=0; j<ny; ++j) {          
            collection[i][j] = std::make_unique<LibraryClass>();            
        }               
    }   
}

void MainClass::init() {
    for (int i=0; i<collection.size(); ++i) {           
        for (int j=0; j<collection[i].size(); ++j) {            
            collection[i][j]->init(i,j);            
        }                   
    }
}

void MainClass::report() {
    for (int i=0; i<collection.size(); ++i) {
        for (int j=0; j< collection[i].size(); ++j) {
            collection[i][j]->report();
        }
    }
}

int main() {
    int nx = 3;
    int ny = 4;
    MainClass main_class(nx, ny);       
    main_class.init();
    main_class.report();
}

【讨论】:

    猜你喜欢
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-12
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 2013-12-08
    相关资源
    最近更新 更多