vectorlt;unique_ptrlt;Agt; gt; using initialization list(矢量lt;unique_ptrlt;Agt;gt;使用初始化列表)
问题描述
我遇到了一个错误:在编译类似于下面的代码时调用'std::__1::unique_ptr>'的隐式删除的复制构造函数c++ -std=c++14 unique_ptr_vector.cpp -o main
这是一个简化版本:
头文件'my_header.h':
header file 'my_header.h':
#include <iostream>
#include <string>
#include <memory>
#include <vector>
class A{
public:
A() : n(0) {}
A(int val) : n(val) {}
A(const A &rhs): n(rhs.n) {}
A(A &&rhs) : n(std::move(rhs.n)) {}
A& operator=(const A &rhs) { n = rhs.n; return *this; }
A& operator=(A &&rhs) { n = std::move(rhs.n); return *this; }
~A() {}
void print() const { std::cout << "class A: " << n << std::endl; }
private:
int n;
};
namespace {
std::vector<std::unique_ptr<A>> vecA = {
std::make_unique<A>(1),
std::make_unique<A>(2),
std::make_unique<A>(3),
std::make_unique<A>(4)
};
}
还有我的 src 文件 unique_ptr_vector.cpp
:
And my src file unique_ptr_vector.cpp
:
#include "my_header.h"
using namespace std;
int main()
{
for(const auto &ptrA : vecA){
ptrA->print();
}
return 0;
}
我真的需要为每个组件单独使用 push_back(std::make_unique(
,或者在标题中填充容器的首选方法是什么?或者这是一个坏主意?
Do I really need to use push_back(std::make_unique<A>(<some_number>))
individually for each component,
Or what would be a preferred way to populate a container in a header? Or is this a bad idea in general?
我看到了诸如 这个,这个和这个.
我现在知道初始化列表似乎是不可能的.但是人们通常用 container
做什么.我是否应该简单地避免在标题中对其进行初始化...
I know now Initialization list seems impossible. but what do people normally do with container<unique_ptr>
. Should I just simply avoid initialize that in a header...
推荐答案
初始化列表是 const
数组的包装器.
Initialization lists are wrappers around const
arrays.
unique_ptr
是 const
不能移动.
我们可以像这样(以完全合法的方式)解决这个问题:
We can hack around this (in a perfectly legal way) like this:
template<class T>
struct movable_il {
mutable T t;
operator T() const&& { return std::move(t); }
movable_il( T&& in ): t(std::move(in)) {}
};
template<class T, class A=std::allocator<T>>
std::vector<T,A> vector_from_il( std::initializer_list< movable_il<T> > il ) {
std::vector<T,A> r( std::make_move_iterator(il.begin()), std::make_move_iterator(il.end()) );
return r;
}
实例.
使用:
auto v = vector_from_il< std::unique_ptr<int> >({
std::make_unique<int>(7),
std::make_unique<int>(3)
});
如果你想知道为什么初始化器列出引用常量数据,你必须追踪并阅读委员会会议记录或询问当时在场的人.我猜这是关于最小惊讶原则和/或对可变数据和视图类型有缺陷的人(例如将 array_view
重命名为 span
).
If you want to know why initializer lists reference const data, you'll have to track down and read committee minutes or ask someone who was there. I'd guess it is about the principle of least surprise and/or people with bugaboos about mutable data and view types (such as the renaming of array_view
to span
).
如果你想要的不仅仅是向量:
If you want more than just vectors:
template<class C, class T=typename C::value_type>
C container_from_il( std::initializer_list< movable_il<T> > il ) {
C r( std::make_move_iterator(il.begin()), std::make_move_iterator(il.end()) );
return r;
}
仍然需要按摩才能与关联容器一起工作,因为我们还想移动键.
which still needs massaging to work right with associative containers as we also want to move the key.
template<class VT>
struct fix_vt {
using type=VT;
};
template<class VT>
using fix_vt_t = typename fix_vt<VT>::type;
template<class VT>
struct fix_vt<const VT>:fix_vt<VT>{};
template<class K, class V>
struct fix_vt<std::pair<K,V>>{
using type=std::pair<
typename std::remove_cv<K>::type,
typename std::remove_cv<V>::type
>;
};
template<class C, class T=fix_vt_t<typename C::value_type>>
C container_from_il( std::initializer_list< movable_il<T> > il ) {
C r( std::make_move_iterator(il.begin()), std::make_move_iterator(il.end()) );
return r;
}
这篇关于矢量<unique_ptr<A>>使用初始化列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:矢量<unique_ptr<A>>使用初始化列表
基础教程推荐
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 使用从字符串中提取的参数调用函数 2022-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 从 std::cin 读取密码 2021-01-01