代码之家  ›  专栏  ›  技术社区  ›  Kraken

我应该把这个使用push\u back的代码改成使用std::move吗?

  •  3
  • Kraken  · 技术社区  · 7 年前

    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))

    2 回复  |  直到 7 年前
        1
  •  5
  •   Omnifarious    7 年前

    根据我得到的评论,我决定用不同的方法来回答这个问题。下面是一个程序,它使用各种方法将对象添加到向量中。这个程序精确地打印出在所有情况下调用的复制构造函数、移动构造函数、复制操作符、移动操作符和析构函数。

    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()
    


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

        2
  •  0
  •   Hamza.S    7 年前

    问:应该用什么?

    //后侵位将元素构造到位。

    emplace_back("element");
    

    //push\ u back将创建新对象,然后复制(或移动)其参数值。

    push_back(explicitDataType{"element"});
    

    所以你应该用这个 emplace_back() std::move() .

    推荐文章