2013-08-24 43 views
6

Tôi đang viết một thư viện chuẩn C++ chuẩn để học.Trả về std :: move (f) in std :: for_each

Tiêu chuẩn C++ 11 cho biết for_each trả về std::move(f).

template <class InputIterator, class Function> 
Function for_each(InputIterator first, InputIterator last, Function f); 

Returns: std::move(f). 

Tôi nghĩ rằng biến địa phương phạm vi chức năng được di chuyển xây dựng khi nó được trả về. Tôi có nên trả lại move(f) một cách rõ ràng không?

+3

Trong trường hợp này, trả về 'std :: move (f)' là * gần * tương đương với trả về 'f'. C++ 11 cấm tối ưu hóa giá trị trả về cho các tham số hàm (nhưng vẫn cho phép di chuyển ngầm cho chúng). Vì vậy, sự khác biệt duy nhất, có vẻ như với tôi, là 'return f;' rơi trở lại xem xét nó như là một giá trị nếu giá trị sẽ gây ra sự mơ hồ quá tải hoặc sẽ không tìm thấy hàm tạo. Nhưng 'return move (f)' sẽ thất bại với sự hình thành không đúng trong trường hợp này. –

+1

Ví dụ, hành vi sẽ khác với 'Hàm' được định nghĩa như hàm' struct {function (function &) '; }; '. Lớp này không có hàm khởi tạo, và một hàm tạo bản sao không chấp nhận các giá trị. Sự trở lại 'move (f)' sẽ có dạng không đúng, trong khi 'return f;' sẽ được tạo thành tốt. –

+1

Nhưng sau đó một lần nữa, tôi không chắc chắn những hạn chế về thư viện cho các đối tượng hàm là gì. Có lẽ chúng yêu cầu 'Hàm' được sao chép có thể khởi tạo từ các giá trị. Trong trường hợp đó thực sự sẽ không có sự khác biệt, theo như tôi thấy. –

Trả lời

2

Từ Josuttis 's C thư viện chuẩn ++

Bạn không cần phải và không nên di chuyển() giá trị trả về. Theo các quy tắc ngôn ngữ, tiêu chuẩn quy định rằng đối với đoạn mã sau

X foo() 
{ 
X x; 
... 

return x; 
} 

các hành vi sau đây được đảm bảo:

• Nếu X có một bản sao tiếp cận hoặc di chuyển constructor, trình biên dịch có thể chọn để bõ mẫu âm chót các sao chép. Đây là cái gọi là (có tên) giá trị trả về tối ưu hóa ((N) RVO), được chỉ định ngay cả trước C++ 11 và là được hỗ trợ bởi hầu hết các trình biên dịch.

• Nếu không, nếu X có một hàm tạo di chuyển, x sẽ được di chuyển.

• Nếu không, nếu X có một hàm tạo bản sao, x sẽ được sao chép.

• Nếu không, lỗi biên dịch sẽ được phát ra.

Từ §25.2.4 (for_each)

Yêu cầu: Chức năng phải đáp ứng các yêu cầu của MoveConstructible (Bảng 20). [Lưu ý: Chức năng không cần phải đáp ứng các yêu cầu của CopyConstructible (Bảng 21) .- cuối note]

Với std::move(f) bạn có thể được đảm bảo về khả năng đọc tình trạng biến đổi bên ngoài.

+0

Tôi đã bỏ lỡ yêu cầu của 'Chức năng'. Cám ơn. – kukyakya

+1

Tuy nhiên, câu hỏi hỏi về tham số hàm "f" trong khi tiêu chuẩn thay cho một ví dụ với biến cục bộ. RVO có áp dụng cho các tham số chức năng không? – Hugues

Các vấn đề liên quan