#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
class Base {
public:
virtual ~Base() = default;
virtual void doIt() = 0;
public:
int base = 1;
};
class Derived : public Base{
public:
Derived(int x) : derived(x) { base = x; }
void doIt() override { printf("hello from derived class. %d, %d\n", derived, base); }
public:
int derived = 2;
};
class Storage {
public:
std::map<std::string, std::vector<std::vector<std::unique_ptr<Base>>>> cache;
void add_to_cache(std::unique_ptr<Base> ptr) {
cache["row"].back().push_back(std::move(ptr));
}
void add_new_cacheLine() {
cache.emplace("row", std::vector<std::vector<std::unique_ptr<Base>>>{}); // Case I: compile ok.
/*
std::vector<std::vector<std::unique_ptr<Base>>> emptyCacheLine{};
cache.insert("row", emptyCacheLine); // Case II: compile error
*/
}
Storage() {
cache["row"] = {};
}
};
int main()
{
Storage storage;
storage.add_to_cache(std::make_unique<Derived>(3));
for (auto& s : storage.cache["row"].back()) {
s->doIt();
}
}
这是我的示例代码,当使用案例 II 的 MSVC 编译它时,我得到:
Error C2280 'std::unique_ptr<Base,std::default_delete<Base>> &std::unique_ptr<Base,std::default_delete<Base>>::operator =(const std::unique_ptr<Base,std::default_delete<Base>> &)': attempting to reference a deleted function
完整的构建日志在这里:
Build started...
1>------ Build started: Project: ConsoleApplication1, Configuration: Debug x64 ------
1>ConsoleApplication1.cpp
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory(677,47): error C2280: 'std::unique_ptr<Base,std::default_delete<Base>>::unique_ptr(const std::unique_ptr<Base,std::default_delete<Base>> &)': attempting to reference a deleted function
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\memory(3317,5): message : see declaration of 'std::unique_ptr<Base,std::default_delete<Base>>::unique_ptr'
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\memory(3317,5): message : 'std::unique_ptr<Base,std::default_delete<Base>>::unique_ptr(const std::unique_ptr<Base,std::default_delete<Base>> &)': function was explicitly deleted
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory(1777,35): message : see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,std::unique_ptr<Base,std::default_delete<Base>>&>(_Alloc &,_Objty *const ,std::unique_ptr<Base,std::default_delete<Base>> &)' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>,
1> _Ty=std::unique_ptr<Base,std::default_delete<Base>>,
1> _Objty=std::unique_ptr<Base,std::default_delete<Base>>
1> ]
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory(1831,17): message : see reference to function template instantiation 'void std::_Uninitialized_backout_al<std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>>::_Emplace_back<std::unique_ptr<Base,std::default_delete<Base>>&>(std::unique_ptr<Base,std::default_delete<Base>> &)' being compiled
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\vector(2072,36): message : see reference to function template instantiation 'std::unique_ptr<Base,std::default_delete<Base>> *std::_Uninitialized_copy<std::unique_ptr<Base,std::default_delete<Base>>*,std::unique_ptr<Base,std::default_delete<Base>>*,std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>>(_InIt,_Se,std::unique_ptr<Base,std::default_delete<Base>> *,_Alloc &)' being compiled
1> with
1> [
1> _InIt=std::unique_ptr<Base,std::default_delete<Base>> *,
1> _Se=std::unique_ptr<Base,std::default_delete<Base>> *,
1> _Alloc=std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>
1> ]
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\vector(684,9): message : see reference to function template instantiation 'void std::vector<std::unique_ptr<Base,std::default_delete<Base>>,std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>>::_Construct_n<std::unique_ptr<Base,std::default_delete<Base>>*const &,std::unique_ptr<Base,std::default_delete<Base>>*const &>(const unsigned __int64,std::unique_ptr<Base,std::default_delete<Base>> *const &,std::unique_ptr<Base,std::default_delete<Base>> *const &)' being compiled
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\vector(680,5): message : while compiling class template member function 'std::vector<std::unique_ptr<Base,std::default_delete<Base>>,std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>>::vector(const std::vector<std::unique_ptr<Base,std::default_delete<Base>>,std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>> &)'
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory(677,47): message : see the first reference to 'std::vector<std::unique_ptr<Base,std::default_delete<Base>>,std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>>::vector' in 'std::_Default_allocator_traits<_Alloc>::construct'
1> with
1> [
1> _Alloc=std::allocator<std::vector<std::unique_ptr<Base,std::default_delete<Base>>,std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>>>
1> ]
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory(1777,44): message : see the first reference to 'std::_Default_allocator_traits<_Alloc>::construct' in 'std::_Uninitialized_backout_al<std::allocator<std::vector<std::unique_ptr<Base,std::default_delete<Base>>,std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>>>>::_Emplace_back'
1> with
1> [
1> _Alloc=std::allocator<std::vector<std::unique_ptr<Base,std::default_delete<Base>>,std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>>>
1> ]
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\xmemory(1831,31): message : see the first reference to 'std::_Uninitialized_backout_al<std::allocator<std::vector<std::unique_ptr<Base,std::default_delete<Base>>,std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>>>>::_Emplace_back' in 'std::_Uninitialized_copy'
1>C:\Users\xxx\source\repos\ConsoleApplication1\ConsoleApplication1.cpp(30,1): message : see reference to class template instantiation 'std::vector<std::unique_ptr<Base,std::default_delete<Base>>,std::allocator<std::unique_ptr<Base,std::default_delete<Base>>>>' being compiled
1>Done building project "ConsoleApplication1.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
========== Build started at 2:48 PM and took 00.963 seconds ==========
我知道 unique_ptr 无法复制,但是有没有办法可以使用 unique_ptr 的向量作为 std::map 内的值?
emptyCacheLine.push_back({})
,因为目前在cache["tag"].back()
中调用add_to_cache
时会出现运行时错误。非常感谢!如果你想初始化
emptyCacheLine
std::vector
,可以使用以下方法:class Storage {
public:
std::map<std::string, std::unique_ptr<std::vector<std::unique_ptr<Base>>>> cache;
void add_to_cache(std::unique_ptr<Base> ptr) {
if (cache["row"]->empty())
cache["row"]->emplace_back(); // Add an empty vector if none exists
cache["row"]->back().push_back(std::move(ptr));
}
void add_new_cacheLine() {
cache.emplace("row", std::make_unique<std::vector<std::unique_ptr<Base>>>());
}
Storage() {
cache["row"] = std::make_unique<std::vector<std::unique_ptr<Base>>>();
// To initialize with one empty vector
cache["row"]->emplace_back();
}
};
现在,当您调用
add_to_cache
时,它会检查地图内的 std::vector
是否为空。如果是,它会在将 std::vector
推入向量之前添加一个空的 unique_ptr
。这样,您将避免调用 cache["row"]->back()
时出现运行时错误。
此外,在
Storage
cache["row"]->emplace_back();
来初始化 emptyCacheLine
,其中包含一个空的 std::vector
。对于缓存类型
std::map<std::string, std::vector<std::vector<std::unique_ptr<Base>>>>
,您可以在构造函数中使用一个空向量来初始化最里面的向量,如下所示:
class Storage {
public:
std::map<std::string, std::vector<std::vector<std::unique_ptr<Base>>>> cache;
void add_to_cache(std::unique_ptr<Base> ptr) {
if (cache["row"].empty())
cache["row"].emplace_back(); // Add an empty vector if none exists
cache["row"].back().push_back(std::move(ptr));
}
void add_new_cacheLine() {
cache.emplace("row", std::vector<std::vector<std::unique_ptr<Base>>>{});
}
Storage() {
cache["row"].push_back(std::vector<std::unique_ptr<Base>>()); // To initialize with one empty vector
}
};
当你调用
add_to_cache
时,它会检查地图内最里面的向量是否为空。如果是,它会在将 unique_ptr
推入向量之前添加一个空向量。在构造函数中,我们用一个空向量初始化 cache["row"]
。
这应该适用于您给定的
cache
类型的具体情况。