2013-06-17 43 views
18

Các mô tả cho dàn diễn viên tĩnh nóicó bất kỳ sự khác biệt giữa dàn diễn viên tĩnh để tham khảo rvalue và std :: di chuyển

Nếu NEW_TYPE là một loại tài liệu tham khảo rvalue, static_cast chuyển đổi giá trị của biểu thức để Xvalue. Loại static_cast này được sử dụng để triển khai ngữ nghĩa di chuyển trong std :: move. (Kể từ C++ 11)

Điều này có xác nhận rằng điều sau đây là tương đương?

(A)

X x1; 
X x2 = static_cast<X&&>(x1); 

(B)

X x1; 
X x2 = std::move(x1); 
+4

Họ là tương đương nhưng thái này là ít bị lỗi. – user1353535

Trả lời

31

Có có một sự khác biệt rất quan trọng: std::move tài liệu những gì bạn muốn làm. Ngoài ra, diễn viên có thể dễ dàng viết các lỗi như bị lãng quên & hoặc sai loại X.

Có thể thấy, std::move thậm chí còn ít hơn để nhập.

+3

Tôi sử dụng "' static_cast '" chỉ khi 'di chuyển' là * không *' constexpr' và tôi cần thuộc tính đó. – CTMacUser

1

T & & Trong C++ 11 là tham chiếu rValue. Chúng hoạt động giống như tham chiếu lvalue từ C++ 98,03. Mục tiêu của họ - là một ứng viên di chuyển. Trong C++ 98, việc xây dựng như vậy có thể xuất hiện trong refrence collapsing

std :: move - biểu thức lượt trong rvalue. Nó có thể được gọi là rvalue_cast, nhưng từ khóa đó không tồn tại.

Trích xuất rõ ràng để nhập T & & có thể về nguyên tắc. Bất standart tốn một số tiền, nhưng trong dự thảo của ISO/IEC 14882:2011 Có tồn tại thông tin như vậy

5.2.9 Static đúc

8)

Các giá trị trái-to-rvalue (4.1), mảng chuyển đổi con trỏ (4.2) và chuyển đổi chức năng thành con trỏ (4.3) được áp dụng cho toán hạng ....

Từ quan điểm thực tế, thuận tiện hơn khi sử dụng lệnh std :: move. Hãy tưởng tượng ví dụ như:

#include <stdio.h> 
#include <utility> 

class A 
{ 
public: 
A() {printf ("A()" "\n");} 
A (const A &) {printf ("A (&)" "\n");} 
A (A &&) {printf ("A (&&)" "\n");} 
A (const A &&) {printf ("A (const &&)" "\n");} 
~ A() {printf ("~ A()" "\n");} 
}; 


int main() 
{ 
const A obj; 
A obj2 (std::move (obj)); // 1-st approach 
A obj3 (static_cast <const A&&> (obj)); // 2-nd approach 
} 

Đối với tôi 1-st cách tiếp cận là

  • thuận tiện hơn (bạn nên thực hiện static_cast để const Một & &, hoặc để Một & &?)
  • một cách rõ ràng hơn (tôi có thể sử dụng tìm kiếm trong soạn thảo văn bản để tìm std :: di chuyển trong dự án)
  • ít dễ bị lỗi khi phát triển phần mềm viết mã
+0

không cần một 'rvalue_cast' _keyword_. Chỉ cần làm 'mẫu mẫu constexpr auto rvalue_cast (T && t) {return std :: move (t); }; 'nếu bạn thực sự muốn sử dụng tên đó. – rubenvb

-1

Bạn có thể sử dụng static_cast<A &&>(a) khi a là một rvalue, nhưng bạn không nên sử dụng std::move(a).
Khi bạn sử dụng A && a = std::move(A()), bạn sẽ nhận được một tham chiếu đáng yêu.

Ý tưởng cơ bản là tuổi thọ của tạm thời không thể được mở rộng thêm bằng cách "chuyển nó lên": tham chiếu thứ hai, được khởi tạo từ tham chiếu mà tạm thời bị ràng buộc, không ảnh hưởng đến tuổi thọ của nó.

std::move 's thực hiện có phần giống như

template <typename T> 
constexpr decltype(auto) move(T && __t) noexcept // when used in std::move(A()), 
                // the lifetime of the temporary object is extended by __t 
{ 
    return static_cast<typename std::remove_reference<T>::type &&>(__t); // a xvalue returned, no lifetime extension 
} 

auto && a = std::move(A()); // the anonymous object wiil be destructed right after this line 
+0

Tôi không thấy làm thế nào bạn nhận được tham khảo lủng lẳng trong ví dụ thứ hai của bạn. Ngoài ra, có gì sai với 'std :: move (a)' khi 'a' là một rvalue? Kết quả của 'std :: move ((const int &) a)' chỉ là 'const int &&', đó là những gì bạn muốn. – SirGuy

+0

@SirGuy Một ràng buộc tạm thời với tham số tham chiếu trong một cuộc gọi hàm tồn tại cho đến khi kết thúc biểu thức đầy đủ chứa hàm đó: nếu hàm trả về một tham chiếu, biểu thức này xuất hiện ở dạng đầy đủ, nó trở thành tham chiếu lơ lửng. 'move' lấy tham chiếu rvalue cho biểu thức prvalue được đúc sẵn làm đối số. –

+0

'A && a = std :: di chuyển (A());' sẽ là một tham chiếu lơ lửng (như phiên bản tĩnh của cùng loại) ... 'A a' không phải là tham chiếu, do đó không phải là tham chiếu –