您可以使用初始化列表中的 unique_ptr 初始化 STL 容器吗?
Can you initialize an STL container with unique_ptr from an initializer list?
我想知道这个。考虑一下:
#include <iostream>
#include <map>
#include <memory>
int main() {
std::map< int, std::unique_ptr<int> > m =
{ { 1, std::unique_ptr<int>(new int(3)) } };
return(0);
}
这是 C++11。它无法编译,并在 GCC 上出现大量错误消息,其中包括一个
/usr/include/c++/4.9/ext/new_allocator.h:120:4: error: use of deleted function ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int; _T2 = std::unique_ptr<int>]’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
有没有可能做我在这里想做的事情?我注意到使用 shared_ptr,它工作正常。可以用 unique_ptr 来做吗?如果是这样,我错过了什么?如果不是,为什么不呢?
没有
无法修改 initializer_list
的元素。
unique_ptr
不能被移动(因为它是常量)也不能被复制(因为它是一个只能移动的类型),所以你完蛋了。
好的,没问题。
首先,智能 unique_ptr 代理,因此我们可以在 const
上下文中创建和移动它们:
template<class T>
struct il_up {
mutable std::unique_ptr<T> ptr;
template<class U,
std::enable_if_t< std::is_convertible<U*, T*>{}, int>* =nullptr
>
il_up( std::unique_ptr<U> o ): ptr(std::move(o)) {}
operator std::unique_ptr<T>() const {
return std::move(ptr);
}
};
然后我们想将其存储在 initializer_list 中。即使是const
,也能把unique_ptr
传出去
然后是一个容器制作代理来存储临时初始化列表:
template<class T>
struct make_container {
std::initializer_list<T> il;
make_container( std::initializer_list<T> const& l ):il(l) {} // const& here matters
template<class C>
operator C()&&{
return {il.begin(), il.end()};
}
};
我们完成了:
std::vector<std::unique_ptr<int>> vec = make_container<il_up<int>>{
std::make_unique<int>(1), std::make_unique<int>(2),
std::make_unique<int>(3), std::make_unique<int>(4)
};
我想知道这个。考虑一下:
#include <iostream>
#include <map>
#include <memory>
int main() {
std::map< int, std::unique_ptr<int> > m =
{ { 1, std::unique_ptr<int>(new int(3)) } };
return(0);
}
这是 C++11。它无法编译,并在 GCC 上出现大量错误消息,其中包括一个
/usr/include/c++/4.9/ext/new_allocator.h:120:4: error: use of deleted function ‘constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = const int; _T2 = std::unique_ptr<int>]’ { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
有没有可能做我在这里想做的事情?我注意到使用 shared_ptr,它工作正常。可以用 unique_ptr 来做吗?如果是这样,我错过了什么?如果不是,为什么不呢?
没有
无法修改 initializer_list
的元素。
unique_ptr
不能被移动(因为它是常量)也不能被复制(因为它是一个只能移动的类型),所以你完蛋了。
好的,没问题。
首先,智能 unique_ptr 代理,因此我们可以在 const
上下文中创建和移动它们:
template<class T>
struct il_up {
mutable std::unique_ptr<T> ptr;
template<class U,
std::enable_if_t< std::is_convertible<U*, T*>{}, int>* =nullptr
>
il_up( std::unique_ptr<U> o ): ptr(std::move(o)) {}
operator std::unique_ptr<T>() const {
return std::move(ptr);
}
};
然后我们想将其存储在 initializer_list 中。即使是const
,也能把unique_ptr
传出去
然后是一个容器制作代理来存储临时初始化列表:
template<class T>
struct make_container {
std::initializer_list<T> il;
make_container( std::initializer_list<T> const& l ):il(l) {} // const& here matters
template<class C>
operator C()&&{
return {il.begin(), il.end()};
}
};
我们完成了:
std::vector<std::unique_ptr<int>> vec = make_container<il_up<int>>{
std::make_unique<int>(1), std::make_unique<int>(2),
std::make_unique<int>(3), std::make_unique<int>(4)
};