[英]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()中的“原始”指針是否有效?
不,這不是安全的。 參數的評估順序未在標准中指定。 因此,您的代碼可以運行為:
std::move(p)
。 std::unique_ptr<int>
move構造函數。 p.get()
(由於為2,因此將為nullptr
)並傳遞此參數。 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.