2013-07-25 28 views
12

Tôi có điều này chương trình ví dụ:đèo mẫu args bởi const & hoặc &&

#include <iostream> 

template<typename Message, typename Decoration, typename PrintImpl> 
void print_surrounded(Message&& msg, const Decoration& decoration, const PrintImpl& print_impl) 
{ 
    print_impl(decoration); // should forward be used? 
    print_impl(" "); 
    print_impl(std::forward<Message>(msg)); 
    print_impl(" "); 
    print_impl(decoration); 
} 

template<typename Message, typename PrintImpl> 
void pretty_print(Message&& msg, const PrintImpl& print_impl) 
{ 
    print_surrounded(std::forward<Message>(msg), "***", print_impl); 
} 

int main() 
{ 
    pretty_print("So pretty!", [](const char* msg) { 
     std::cout << msg; 
    }); 
} 

I also posted it on Coliru.

Như bạn có thể thấy tôi sử dụng nhiều cách khác nhau để vượt qua các đối số:

  • nhắn được truyền như một tham chiếu phổ quát vì nó cuối cùng cần phải được chuyển tiếp đến chức năng PrintImpl.
  • Trang trí được chuyển thành const ref ở đây vì giá trị của nó được sử dụng hai lần và tôi không chắc chắn nếu sử dụng chuyển tiếp hai lần sẽ an toàn. (Nó có thể bị dời đi bởi lần chuyển tiếp đầu tiên?)
  • PrintImpl được chuyển thành tham chiếu const bởi vì tôi không thấy bất kỳ lý do nào để sử dụng chuyển tiếp. Tuy nhiên, tôi không chắc chắn nếu điều này là khôn ngoan. (Tôi có nên vượt qua &&? Nếu có, tôi cũng nên sử dụng std::forward?)

Tôi có lựa chọn đúng không?

+0

Đây không phải là điều tôi hiểu CPS. http://en.wikipedia.org/wiki/Continuation-passing_style Ngoài ra, trong dòng chú thích, tôi giả sử bạn đang hỏi liệu có nên sử dụng 'forward' với' print_impl', không phải 'trang trí', đúng không? – sehe

+0

@sehe Được rồi, tôi đã xóa các phần CPS. – StackedCrooked

+0

Chỉ cần làm rõ: là "nắm bắt" cụm từ chính xác ở đây? Tôi nghĩ rằng "chụp" được dành riêng cho việc nắm bắt các biến bởi các đối tượng đóng cửa (được tạo ra bởi các biểu thức lambda). Không phải là "vượt qua" (của một đối số) các thuật ngữ chính xác? – Walter

Trả lời

4

Tôi có lựa chọn đúng không?

Có (chủ yếu).

Trang trí được chụp dưới dạng const ref ở đây vì giá trị của nó được sử dụng hai lần và tôi không chắc chắn nếu sử dụng chuyển tiếp hai lần sẽ an toàn. (Nó có thể được chuyển đi bởi tiền đạo đầu tiên?)

Không sử dụng std::forward khi bạn muốn làm điều đó nhiều lần, chính xác vì lý do bạn đặt ra.

PrintImpl được chụp dưới dạng tham chiếu const vì tôi không thấy bất kỳ lý do nào để sử dụng chuyển tiếp.

Những gì bạn có thể muốn làm là lấy PrintImpl&& và không sử dụng std::forward (giữ chúng như lvalues), cho phép đối tượng chức năng mà không const -qualified operator() để được thông qua.

+1

Và nếu bạn cực kỳ ngớ ngẩn, bạn có thể 'std :: forward (print_impl)()' trong lời gọi cuối cùng tới 'print_impl' trong hàm của bạn, trong trường hợp' PrintImpl' của bạn có toán tử '&&' qualified'() '. (Lưu ý: không ai có toán tử '&&' đủ điều kiện '()') – Yakk

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