簡體   English   中英

C ++ 11:在參數列表上調用std :: move()

[英]C++11: std::move() call on arguments' list

當在該對象上還調用了std :: move()時,對該參數列表中的對象進行操作是否安全?

void foo(int* raw, std::unique_ptr<int> u)
{
    *raw = 456;
}

std::unique_ptr<int> p(new int(123));
foo(p.get(), std::move(p));

如果將std :: move(p)評估為第一個參數,則foo()中的“原始”指針是否有效?

不,這不是安全的。 參數的評估順序在標准中指定。 因此,您的代碼可以運行為:

  1. std::move(p)
  2. 調用std::unique_ptr<int> move構造函數。
  3. p.get() (由於為2,因此將為nullptr )並傳遞此參數。
  4. foo

您必須這樣做:

int *raw = p.get();
foo(raw, std::move(p));

以下是有關參數求值順序的答案 -簡而言之: 該順序未在標准中指定,並且因平台,編譯器和調用約定而異。

但是我想測試一下,因此以下是Cygwin GCC的結果:

#include <iostream>
#include <memory>
using namespace std;
void print(int* p) {
    cout << (p == nullptr ? "null" : "valid") << endl; }
void foo(int* p, unique_ptr<int> u) {
    print(p); }
void bar(unique_ptr<int> u, int* p) {
    print(p); }
__stdcall void foo2(int* p, unique_ptr<int> u) {
    print(p); }
__stdcall void bar2(unique_ptr<int> u, int* p) {
    print(p); }
__cdecl void foo3(int* p, unique_ptr<int> u) {
    print(p); }
__cdecl void bar3(unique_ptr<int> u, int* p) {
    print(p); }
int main() {
    unique_ptr<int> p(new int(1)), q(new int(2));
    foo(p.get(), move(p)); bar(move(q), q.get());
    unique_ptr<int> p2(new int(1)), q2(new int(2));
    foo2(p2.get(), move(p2)); bar2(move(q2), q2.get());
    unique_ptr<int> p3(new int(1)), q3(new int(2));
    foo3(p3.get(), move(p3)); bar3(move(q3), q3.get());
}

輸出:

null
valid
null
valid
null
valid

令人驚訝的是,即使使用__stdcall__cdecl ,我也不能強迫它更改順序。

編輯 :與MSVC 2012 (__stdcall / __ cdecl在名稱前移動)相同的測試, 相同的結果

在參數上調用std::move()是完全安全的。

不安全的做法是通過寫入由對象管理的原始指針來使自己陷入困境,該對象已將指針的內存交還給免費存儲。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM