2013-07-25 44 views
12

我有這樣的例子程序:以const通行證模板ARGS&或&&

#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.

正如你可以看到我用不同的方式來傳遞參數:

  • 消息傳遞作爲通用參考,因爲它最終需要轉發給PrintImpl函數。
  • 裝飾作爲常量參考在這裏傳遞,因爲它的值被使用兩次,我不確定是否使用向前兩次是安全的。 (它可能會被第一個前進移開?)
  • PrintImpl作爲常量引用傳遞,因爲我看不到任何使用forward的理由。但是,我不確定這是否明智。 (我應該通過&&通過了嗎?如果是的話,是否也應該使用std::forward?)

我是否做出了正確的選擇呢?

+0

這不正是我所瞭解的CPS的意思。 http://en.wikipedia.org/wiki/Continuation-passing_style另外,在評論的一行中,我假設你問是否使用'forward'與'print_impl',而不是'decoration',對吧? – sehe

+0

@sehe好吧,我刪除了CPS部分。 – StackedCrooked

+0

只是爲了澄清:在這裏「捕捉」正確的術語?我認爲「捕獲」保留用於通過閉包對象捕獲變量(由lambda表達式生成)。是不是「通過」(爭論)正確的術語? – Walter

回答

4

我做出正確的選擇嗎?

是(大部分)。

裝飾在此被捕獲爲const ref,因爲它的值被使用了兩次,我不確定是否使用向前兩次是安全的。 (它可能通過第一向前移動了嗎?

不要使用std::forward當你多次這樣做,正是爲你奠定了原因。

PrintImpl被捕獲爲常量引用,因爲我沒有看到任何使用forward的理由。

什麼,你可能想要做的是採取PrintImpl&&和不使用std::forward(它們保持爲左值),允許函數對象,而不const -qualified operator()傳遞。

+1

而且,如果你非常愚蠢,你可以在函數中最後一次調用print_impl函數時'std :: forward (print_impl)()',以防你的'PrintImpl'有一個&&''限定的'操作符()'。 (注意:沒有人擁有'&&''合格'操作符()') – Yakk