+-
c – 我应该更改使用push_back来使用std :: move的代码吗?
我刚刚阅读了关于rvalue引用的内容,下面是我所指的代码

vector<string> v;
string s = "hello";   

v.push_back(s); 
cout << s << endl;
cout << v[0] << endl;
return 0

我的问题是,到目前为止,每当我看到对象(或字符串)的向量时,我主要看到插入操作如上所述.相反,如果我做v.push_back(std :: move(s)),那么我不会不必要地创建重复的对象.

这应该是向STL添加对象的正确方法,我们关心的只是容器中的数据而不是其他变量.

最佳答案
鉴于我得到的评论,我已经决定采用不同的方法来解决这个问题.这是一个程序,它使用各种方法将对象添加到矢量.该程序准确打印出在所有情况下都调用哪些复制构造函数,移动构造函数,复制运算符,移动运算符和析构函数.

该程序使用了奇妙的fmt library.而fmt :: print完全符合您的想法.或许,我应该使用:: fmt.请记住,从一个对象移动通常会使其处于未指定状态(注意,与未定义不同)状态.当然,对于你自己编写的课程,你确切地知道它所处的状态.但对于标准的库类或其他人编写的类,你却不知道.显然,对于标准库类,您可以保证,如果您执行某些操作将状态设置为已知的状态,则该对象将确实更改为该状态.

就个人而言,我只是将对象视为从它移动后唯一有效的操作就是调用它的析构函数.但我可以看到您可能只想以某种方式重新使用存储的情况.

这是程序:

#include <fmt/core.h> // fmt
#include <vector>  // vector
#include <utility> // move

class TestClass {
 public:
    TestClass(int a, int b) {
        fmt::print("TestClass{{{}, {}}}\n", a, b);
    }
    TestClass(TestClass const &) noexcept {
        fmt::print("TestClass{{TestClass const &}}\n");
    }
    TestClass(TestClass &&) noexcept {
        fmt::print("TestClass{{TestClass &&}}\n");
    }
    TestClass const &operator =(TestClass const &) noexcept {
        fmt::print("=(TestClass const &)\n");
        return *this;
    }
    TestClass const &operator =(TestClass &&) noexcept {
        fmt::print("=(TestClass &&)\n");
        return *this;
    }
    ~TestClass() noexcept {
        fmt::print("~TestClass()\n");
    }
};

int main()
{
   ::std::vector<TestClass> v;
   // Reserve necessary space so movements of vector elements doesn't clutter up
   // the output.
   v.reserve(6);
   fmt::print("Constructing initial\n");
   TestClass o{1, 2};

   fmt::print("\bv.push_back(o)\n");
   v.push_back(o);

   fmt::print("\nv.push_back(::std::move(o))\n");
   v.push_back(::std::move(o));

   fmt::print("\nv.push_back(TestClass{{3, 4}})\n");
   v.push_back(TestClass{3, 4});

   fmt::print("\nv.emplace_back(5, 6)\n");
   v.emplace_back(5, 6);

   fmt::print("\nv.emplace_back(::std::move(o))\n");
   v.emplace_back(::std::move(o));

   fmt::print("\nv.emplace_back(TestClass{{5, 6}})\n");
   v.emplace_back(TestClass{5, 6});

   fmt::print("\nHere H\n");
}

这是程序的输出:

Constructing initial
TestClass{1, 2}
v.push_back(o)
TestClass{TestClass const &}

v.push_back(::std::move(o))
TestClass{TestClass &&}

v.push_back(TestClass{3, 4})
TestClass{3, 4}
TestClass{TestClass &&}
~TestClass()

v.emplace_back(5, 6)
TestClass{5, 6}

v.emplace_back(::std::move(o))
TestClass{TestClass &&}

v.emplace_back(TestClass{5, 6})
TestClass{5, 6}
TestClass{TestClass &&}
~TestClass()

Here H
~TestClass()
~TestClass()
~TestClass()
~TestClass()
~TestClass()
~TestClass()
~TestClass()

我会说这个程序具有我预期的输出,并且输出(AFAIK)与我之前的答案一致.

Why I use ::std:: instead of std::

点击查看更多相关文章

转载注明原文:c – 我应该更改使用push_back来使用std :: move的代码吗? - 乐贴网