我正在看看C++技術報告1中包含的Boost庫,並試圖理解它們各自的作用。如果我們有boost :: bind,使用boost :: mem_fn有什麼意義?
我剛剛完成爲boost::mem_fn
運行一個示例,現在我想知道使用它的是什麼而不是更好的boost::bind
。據我所知,它們都返回一個指向成員函數的函數對象。我發現mem_fn
如此有限,以至於我無法找到使用它的場景比bind
更好的場景。
我錯過了什麼嗎?有沒有什麼情況下綁定不能取代mem_fn?
我正在看看C++技術報告1中包含的Boost庫,並試圖理解它們各自的作用。如果我們有boost :: bind,使用boost :: mem_fn有什麼意義?
我剛剛完成爲boost::mem_fn
運行一個示例,現在我想知道使用它的是什麼而不是更好的boost::bind
。據我所知,它們都返回一個指向成員函數的函數對象。我發現mem_fn
如此有限,以至於我無法找到使用它的場景比bind
更好的場景。
我錯過了什麼嗎?有沒有什麼情況下綁定不能取代mem_fn?
mem_fn
比bind
小得多,因此,如果您只需要mem_fn
功能是少了很多代碼來拉。
好吧,綁定取決於mem_fun,所以你走了。如何以及爲什麼我會離開你去發現,因爲雖然有趣,但我現在還沒有時間去調查(綁定是複雜的)。
boost::lambda
與您提到的兩個功能有類似的重疊。我認爲它們都是以類似的意圖進行演變的,而且大致同時,採用不同的方法,導致混淆和不兼容問題。如果他們全部合併在一個lambda
傘下,它會很好。
因此,不,沒有總體設計要求兩個圖書館共存。
mem_fn
更小,比bind
更快。用你最喜歡的編譯器試試下面的程序和比較:
您可以通過將#if
行中的1更改爲0來比較bind
與mem_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::_1
像bind does
(在模糊的模板化編譯器錯誤的痛苦)。
所以,如果可以的話,更喜歡mem_fn
。
+1。 – felipou 2014-04-17 10:03:32
我認爲GCC優化將使兩者的速度效率大致相同。我只是用你的代碼使用「-O2」進行測試(並在「bar」函數中打印某些內容,否則優化器將看到它什麼也不做)。有時候「綁定」版本更快。 – felipou 2014-04-17 10:07:41
你應該添加類似'static volatile int i;我;'進入'bar'主體,否則編譯器可能會優化空函數調用(在我的情況下,'bind'和'mem_fn'都發生了什麼)。 'bind'和'mem_fn'的基準測試結果在我的電腦上相同(* gcc 4.9 *,'-O3'),'mem_fn'不會比'bind'更快。 – 2016-04-10 14:01:06
好奇的是,'bind'和'mem_fn'已經使它成爲C++技術報告1,而C++委員會應該是相當嚴格的。他們沒有意識到我們正在複製功能嗎?基準代碼爲 – 2010-06-21 20:48:15