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>>使用初始化列表


基础教程推荐
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 常量变量在标题中不起作用 2021-01-01
- 我有静态或动态 boost 库吗? 2021-01-01
- 这个宏可以转换成函数吗? 2022-01-01
- C++结构和函数声明。为什么它不能编译? 2022-11-07
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- 在 C++ 中计算滚动/移动平均值 2021-01-01