无法用通用引用移动unique_ptr
C++ Unable to move unique_ptr with universal references
考虑以下代码:
template<typename T>
T mov(T&& t){
return std::move(t);
}
int main(){
std::unique_ptr<int> a = std::unique_ptr<int>(new int());
std::unique_ptr<int> b = mov(a);
}
mov
函数应该简单地接受一个通用引用并按值返回它,但通过move
而不是复制它。因此,在调用此方法时不应涉及复制。因此,使用只能移动的unique_ptr
来调用这样的函数应该是好的。但是,这段代码不能编译:我收到错误:
test.cpp:24:34: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
std::unique_ptr<int> b = mov(a);
因此,c++似乎试图调用unique_ptr
的复制构造函数,当然它被删除了。但为什么这里会发生复制呢?我怎样才能得到这个代码编译?
我认为错误是在mov
的返回类型
代码应该是
#include <utility>
#include <memory>
template<typename T>
typename std::remove_reference<T>::type&& mov(T&& t){
return std::move(t);
}
int main(){
std::unique_ptr<int> a = std::unique_ptr<int>(new int());
auto b = mov(a);
}
这个问题暗示了一个按值返回的场景,这也可以编译。我不确定它是否适用于你的情况;
template<typename T>
typename std::remove_reference<T>::type mov(T&& t){
return std::move(t);
}
我终于找到了一个可行的解决方案。我认为问题是按值返回,这将触发一个副本。相反,我需要通过右值引用返回;然后将自动进行移动。首先我试了这个:
template<typename T>
T&& mov(T&& t){
return std::move(t);
}
但是现在,问题是返回类型T&&
是通用引用,而不是右值引用。因此,当调用带有左值的函数时,实际签名是T& mov(T& t)
。因此,它的主体将无法编译,因为我不能将std::move
转换为左值引用。这就是发生的事情,下面是错误:
test.cpp:18:22: error: invalid initialization of non-const reference of type
‘std::unique_ptr<int>&’ from an rvalue of type ‘std::remove_reference<std::unique_ptr<int>&>::type {aka std::unique_ptr<int>}’
return std::move(t);
所以,我需要一个实右值引用作为返回类型。起初,我不知道如何构造它,但最后,我发现我首先需要std::remove_reference
类型T
,然后添加&&
,然后我将有一个实右值引用T&&
。这个版本的mov
编译得很好,解决了这个问题:
template<typename T>
typename std::remove_reference<T>::type&& mov(T&& t){
return std::move(t);
}
正如Niall所说,通过引用返回也可以通过使用remove_reference
而不使用&&
来工作:
template<typename T>
typename std::remove_reference<T>::type mov(T&& t){
return std::move(t);
}
相关文章:
- 将对象移动到std::shared_ptr
- 何时在引用或唯一指针上使用移动语义
- 为什么 std::unique 不调用 std::sort?
- 如何从具有移动语义的类对象中生成共享指针
- 将shared_ptr移动到<StructA>shared_ptr<变体<结构A、结构 B>>
- C / C++ 移位/偏移/向左或向右移动位图?
- MSVC将仅移动结构参数解释为指针
- 自定义先决条件对移动分配运算符有效吗
- 返回值优化:显式移动还是隐式
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- 为什么复制而不是移动数据元素?
- 可以使用移动语义更改或改进此C++代码吗?
- 使lambda不可复制/不可移动
- c++在使用指针时移动语义
- 将QGraphicsItem的移动区域限制在多边形区域内
- SendInput()鼠标移动计算
- 按值 C++ 返回时进行双倍移动
- 移动二维数组中的字符
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- 安全到标准:移动会员?