2010-06-21 81 views
13

我正在看看C++技術報告1中包含的Boost庫,並試圖理解它們各自的作用。如果我們有boost :: bind,使用boost :: mem_fn有什麼意義?

我剛剛完成爲boost::mem_fn運行一個示例,現在我想知道使用它的是什麼而不是更好的boost::bind。據我所知,它們都返回一個指向成員函數的函數對象。我發現mem_fn如此有限,以至於我無法找到使用它的場景比bind更好的場景。

我錯過了什麼嗎?有沒有什麼情況下綁定不能取代mem_fn?

回答

7

mem_fnbind小得多,因此,如果您只需要mem_fn功能是少了很多代碼來拉。

2

好吧,綁定取決於mem_fun,所以你走了。如何以及爲什麼我會離開你去發現,因爲雖然有趣,但我現在還沒有時間去調查(綁定是複雜的)。

1

boost::lambda與您提到的兩個功能有類似的重疊。我認爲它們都是以類似的意圖進行演變的,而且大致同時,採用不同的方法,導致混淆和不兼容問題。如果他們全部合併在一個lambda傘下,它會很好。

因此,不,沒有總體設計要求兩個圖書館共存。

+3

好奇的是,'bind'和'mem_fn'已經使它成爲C++技術報告1,而C++委員會應該是相當嚴格的。他們沒有意識到我們正在複製功能嗎?基準代碼爲 – 2010-06-21 20:48:15

5

mem_fn更小,比bind更快。用你最喜歡的編譯器試試下面的程序和比較:

  1. 生成的可執行文件的大小和
  2. 的報告花費的秒數。

您可以通過將#if行中的1更改爲0來比較bindmem_fn的性能。

#include <iostream> 
#include <functional> 
#include <chrono> 

struct Foo 
{ 
    void bar() {} 
}; 

int main(int argc, const char * argv[]) 
{ 
#if 1 
    auto bound = std::bind(&Foo::bar, std::placeholders::_1); 
#else 
    auto bound = std::mem_fn(&Foo::bar); 
#endif 
    Foo foo; 
    auto start = std::chrono::high_resolution_clock::now(); 
    for(size_t i = 0; i < 100000000; ++i) 
    { 
     bound(foo); 
    } 
    auto end = std::chrono::high_resolution_clock::now(); 
    auto delta = std::chrono::duration_cast< std::chrono::duration<double>>(end - start); 
    std::cout << "seconds = " << delta.count() << std::endl; 
    return 0; 
} 

結果會有所不同,但我目前的系統上mem_fn版本的可執行文件是220個字節更小,運行約兩倍的速度爲bind版本。

而作爲獎勵功能,mem_fn並不要求您記住添加std::placeholders::_1bind does(在模糊的模板化編譯器錯誤的痛苦)。

所以,如果可以的話,更喜歡mem_fn

+0

+1。 – felipou 2014-04-17 10:03:32

+0

我認爲GCC優化將使兩者的速度效率大致相同。我只是用你的代碼使用「-O2」進行測試(並在「bar」函數中打印某些內容,否則優化器將看到它什麼也不做)。有時候「綁定」版本更快。 – felipou 2014-04-17 10:07:41

+0

你應該添加類似'static volatile int i;我;'進入'bar'主體,否則編譯器可能會優化空函數調用(在我的情況下,'bind'和'mem_fn'都發生了什麼)。 'bind'和'mem_fn'的基準測試結果在我的電腦上相同(* gcc 4.9 *,'-O3'),'mem_fn'不會比'bind'更快。 – 2016-04-10 14:01:06

相關問題