发送std::move是正确的方法
Spamming std::move is the way to go?
关于std::move
,以下是我可以解释的,根据http://en.cppreference.com/w/cpp/utility/move:-
- 如果我想转让所有权,我必须调用
std::move
(或在极少数情况下,std::forward
)。 -
std::move
的责任呼叫operator=(A&& other)
。 - 移动操作的最基本步骤应该在
operator=(A&&)
中实现。 - 确保
operator=(A&&)
会被调用是很棘手的。需要一个特殊的转换器。 - c++世界中只有两个转换器可以将变量转换为
xvalue
(&&):std::move
和std::forward
。
在我的代码中添加了许多std::move(std::unique_ptr)
之后,我开始担心像转移所有权这样的基本功能,我必须严重依赖标准库(std::
)。
我真的必须使用std::move
来转移所有权吗?
在代码库的许多地方,垃圾邮件和硬代码调用std::move
是一个高标准程序的正确方法吗?
std::move
应该被封装吗?
它们实际上是一个问题,但是从不同的角度来问。
编辑
应要求,这是我的试用版& &;错误。它可以编译。
我对代码没有问题,但我担心它的方法/模式。https://ideone.com/y8Pcgf
class T{
public: int value;
public: T(int a=1234){
value = a;
}
};
int main() {
std::unique_ptr<T> t1 = std::unique_ptr<T>(new T(1));
void* databaseNew=operator new [](sizeof(std::unique_ptr<T>));
std::unique_ptr<T>* t1ptr=static_cast<std::unique_ptr<T>*>(databaseNew);
new (t1ptr) std::unique_ptr<T>(std::move(t1));
return 0;
}
如果你在一个推断的x值上下文中,使用std::forward
:
template<class T>
void foo(T&& t) // T is deduced x-value, so we forward it
{
bar(std::forward<T>(t));
}
否则使用std::move
template<class T>
void foo1(std::vector<T> v) // although vector<T> is deduced, it's not an x-value
{
bar(std::move(v)); // so move it
}
template<class T>
void foo2(std::vector<T>&& v) // although vector<T> is deduced, it's not an x-value.
// In this case an r-value reference
{
bar(std::move(v)); // so move it
}
template<class T>
void foo3(std::vector<T>& v) // although vector<T> is deduced, it's not an x-value.
// In this case an l-value reference
{
bar(std::move(v)); // so move it
}
void foo4(std::vector<int> v) // complete type
{
bar(std::move(v)); // so move it
}
void foo5(std::vector<int> const & v) // const reference
{
bar(v); // not much point in moving it. std::move would cast it
// to std::vector<int> const&&, which although is detectable
// decays to std::vector<int> const&
}
,虽然可以检测到…怎么啦?
这样写是允许的,但不一定是明智的:
#include <iostream>
struct X
{
void foo() const &
{
// do one thing...
std::cout << "one thingn";
}
void foo() const &&
{
// do something else...
std::cout << "or anothern";
}
};
int main()
{
const X x;
x.foo();
std::move(x).foo();
}
const r值引用确实存在,只是没有人使用它们,因为没有合理的用例。
您所抱怨的显式move
的需要实际上是有意为之。在unique_ptr
之前,STL有一个叫auto_ptr
的可怕构造。它会隐式地移动所有权,并且是不可用的,除非你真的真的真的知道你在做什么。
为了使事情更可用,在大多数情况下,c++现在要求你通过使用std::move
显式地声明你打算转移容器的所有权。
实际上,std::move
只不过是一个对右值引用的强制转换。
在某些情况下,这种明确的说明是不必要的。例如,如果您获得所有权的容器已经是右值(例如-临时对象),则不需要使用std::move
。例如,以下代码不能编译:
std::unique_ptr<int> a;
a = new int;
但是下面的代码可以,不需要移动:
std::unique_ptr<int> a;
a = std::unique_ptr<int>(new int);
尽管调用了move操作符,但不需要调用std::move
的原因是,我们将所有权移开的对象已经是一个临时对象(即-右值),因此不需要强制转换。
另一个例子是,如果你调用一个返回一个unique_ptr的函数。您可能必须在函数内部调用std::move
才能将其放入返回值中,但是您不需要在函数的返回值中调用std::move
来将其放入外部的unique_ptr
中。它已经是右值,因此不需要强制转换。
- 使用std::函数映射对象方法
- 初始化具有非默认构造函数的std::数组项的更好方法
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 为什么 std::span 缺少 cbegin 和 cend 方法?
- 使 std::vector 分配对齐内存的现代方法
- std::find,返回所有找到的值的替代方法,而不仅仅是存在重复的向量的第一个值
- C++ STD 函数运算符:有没有一种方法可以通过函数将一个向量映射到另一个向量上?
- 如何访问存储在 std::variant 中的类的方法
- C++ assigment std::list:<typename>:itrator 在 main 中工作,但在方法中它不起作用
- 我无法使用C++指针指向类方法返回的 std::vector
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 静态 std::map instatiation 在类的方法中调用构造函数吗?
- C++:std::ofstream 方法 open() 在第二次迭代时擦除打开的 ifstream 文件
- 在 std::vector<无符号字符中存储任意数据的方法>
- 将 std:set<int32_t> 复制到 std::set <uint32_t>的好方法
- std::bind,无法让具有单个参数的方法工作
- 连接和压缩标准::vector<std::字符串的最佳方法>
- C++中的多维数据集:从 std::vector 的 2D 数据到 std::vector 的 2D 网格的最干净方法?
- 向后迭代 std::array 或 std::vector 的正确方法是什么?