发送垃圾邮件 std::move 是正确的选择吗?

Spamming std::move is the way to go?

关于std::move,根据http://en.cppreference.com/w/cpp/utility/move,这是我可以解释的:-

问题

在我的代码中添加了很多 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;
}

您抱怨的明确 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);

尽管调用了移动运算符,但不需要调用 std::move 的原因是我们将所有权移出的对象已经是一个临时对象(即 - 一个右值),所以不需要强制转换是必要的。

另一个例子是如果你调用一个 return 是 unique_ptr 的函数。您可能必须在函数内部调用 std::move 才能将其放入 return 值,但您无需在函数的 return 值上调用 std::move 即可将其放入外面 unique_ptr。它已经是一个右值,因此不需要转换。

经验法则:

如果您处于推导的 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&
}

which although is detectable... what?

允许,如果不一定建议这样写代码:

#include <iostream>

struct X
{
  void foo() const &
  {
    // do one thing...
    std::cout << "one thing\n";
  }

  void foo() const &&
  {
    // do something else...
    std::cout << "or another\n";
  }
};

int main()
{
  const X x;
  x.foo();
  std::move(x).foo();
}

const 右值引用确实存在,只是没有人使用它们,因为没有合理的用例。