2012-08-06 43 views
4

我有一些代碼,撒上這樣短路`運營商<<`在C++輸出

if(debug) { 
    Output << "f1: " << f1() << "\n"; 
} 

現在可以構建什麼,我想要做的就是寫一個流類Debug在那裏我可以寫這樣的

Debug << "f1: " << f1() << "\n"; 

如果設置了某個全局標誌,則會生成輸出,否則將生成輸出。

現在:這可以通過使Debug返回一個流到/dev/null這將吞下輸出很容易完成。問題在於f1()仍然會被評估(並且「渲染」爲可能更昂貴的文本表示),這可能對性能非常不利。

現在我的問題:是否有允許的

"f1: " << f1() << "\n" 

完全如果Debug決定「評價」的跳躍,沒有輸出應該做任何把戲?到短路是C++確實爲f() && g()其中g()不評估,如果f()false類似

(我認真考慮編寫使用 &&作爲輸出操作,但是從我讀短路流類未重載 operator&&完成)
+0

[This related question](http://stackoverflow.com/questions/11826554/standard-no-op-output-stream)從今天早些時候可能會有解決方案。 – juanchopanza 2012-08-06 17:23:25

+0

@juanchopanza:那些問題仍然(可能)評估論據。我不認爲這可以按照要求來完成,除非您將格式切換爲類似'DEBUGOUT(「f1:」<< f1()<<「\ n」);' – 2012-08-06 17:30:18

+0

@MooingDuck爲true。他們只避免流媒體。 – juanchopanza 2012-08-06 17:31:43

回答

5

你可以做的就是這個宏定義:

#define Debug_Stream \ 
if(!debug); else Output 

這將使這樣的:

Debug_Stream << "f1: " << f1() << "\n"; 

成爲等價於:

if(debug) { 
    Output << "f1: " << f1() << "\n"; 
} 

但是從字面上(加空格爲可讀性)

if(!debug); 
else 
    Output << "f1: " << f1() << "\n"; 
+2

這樣會容易出現其他不匹配。 – 2012-08-06 17:38:29

+1

@MarkB:可以通過定義'if(!debug); else Output'來修復。 – ybungalobill 2012-08-06 17:40:24

+0

好的標記。並感謝@ybungalobill的建議。我已經改變了解決方案。 – 2012-08-06 17:51:19

4

如果你不是不利宏,並願意接受的語法:

Debug("f1: " << f() << '\n'); 

它很簡單:只要定義是這樣的:

#define Debug(x) debug != NULL && *debug << x; 

然而,這是有點危險,因爲你不能採取通常的 預防措施將參數放在括號內。 (另一方面, 我見過它在很多應用程序中使用,沒有任何問題。) 宏觀方法還有一個額外的優點,即允許您自動插入 __FILE____LINE__(如果需要)。或者通過將 宏定義爲無關, 有條件地抑制全部的代碼。

2

我想你可以通過創建一個包含昂貴的函數調用的延遲評估器來做到這一點。您的流將知道它需要調用引用函數的延遲評估程序類型,否則它將不運行它,從而避免了昂貴的調用。無調試流知道你的代理評估對象只是完全跳過評估。

例如呼叫可能看起來像:

Debug << "123" << delay(f()) << "456" << std::endl; 

這不涉及記憶來調用你的調試行的延遲。它確實避免了宏的需要,這可能會或可能不會成爲您的案例中的關鍵問題。