vector<unique_ptr<A> > 使用初始化列表
vector<unique_ptr<A> > using initialization list
我遇到错误:调用 implicitly-deleted 复制构造函数 'std::__1::unique_ptr >' 编译类似于下面的代码时使用
c++ -std=c++14 unique_ptr_vector.cpp -o main
这是一个简化版本:
header 文件 '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
:
#include "my_header.h"
using namespace std;
int main()
{
for(const auto &ptrA : vecA){
ptrA->print();
}
return 0;
}
我真的需要为每个组件单独使用 push_back(std::make_unique<A>(<some_number>))
吗?
或者在 header 中填充容器的首选方法是什么?或者这通常是个坏主意?
我见过类似 this one, , and 的问题。
我现在知道初始化列表似乎是不可能的。但是人们通常用 container<unique_ptr>
做什么。我是否应该简单地避免在 header...
中初始化它
初始化列表是 const
数组的包装器。
unique_ptr
const
不能是 moved-from.
我们可以像这样(以完全合法的方式)解决这个问题:
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)
});
如果您想知道为什么 初始值设定项列出引用 const 数据,您必须查找并阅读委员会会议记录或询问当时在场的人。我猜这是关于最小惊奇原则 and/or 对可变数据和视图类型有疑虑的人(例如将 array_view
重命名为 span
)。
如果您想要的不仅仅是矢量:
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;
}
仍然需要按摩才能与关联容器一起工作,因为我们还想移动键。
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;
}
我遇到错误:调用 implicitly-deleted 复制构造函数 'std::__1::unique_ptr >' 编译类似于下面的代码时使用 c++ -std=c++14 unique_ptr_vector.cpp -o main
这是一个简化版本:
header 文件 '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
:
#include "my_header.h"
using namespace std;
int main()
{
for(const auto &ptrA : vecA){
ptrA->print();
}
return 0;
}
我真的需要为每个组件单独使用 push_back(std::make_unique<A>(<some_number>))
吗?
或者在 header 中填充容器的首选方法是什么?或者这通常是个坏主意?
我见过类似 this one,
我现在知道初始化列表似乎是不可能的。但是人们通常用 container<unique_ptr>
做什么。我是否应该简单地避免在 header...
初始化列表是 const
数组的包装器。
unique_ptr
const
不能是 moved-from.
我们可以像这样(以完全合法的方式)解决这个问题:
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)
});
如果您想知道为什么 初始值设定项列出引用 const 数据,您必须查找并阅读委员会会议记录或询问当时在场的人。我猜这是关于最小惊奇原则 and/or 对可变数据和视图类型有疑虑的人(例如将 array_view
重命名为 span
)。
如果您想要的不仅仅是矢量:
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;
}
仍然需要按摩才能与关联容器一起工作,因为我们还想移动键。
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;
}