簡體   English   中英

std :: bind和std :: function問題

[英]std::bind and std::function questions

int func(int x){return x;}
...
std::function<int(int)> x = std::bind(func, std::placeholders::_1);
x(123);
  1. x(123)實際上是否調用了生成std::function的functor的operator() ,而后者又調用了最終調用func std::bind生成的functor的operator() 這是否被優化為與調用func(123)一樣最優的東西?
  2. 構造函數在哪里生成std::bind生成的? 在什么范圍? std::bind如何命名呢? (可以有名稱沖突)
  3. lambda可以替換std::bind所有用法嗎?
  4. std::bind是否最適合將其作為lambda實現?
  5. 怎么了std::function的模板參數的語法? 如何解析它以及如何在其他地方使用該模板參數語法?

x(123)實際上是否調用了生成std :: function的functor的operator(),而后者又調用了最終調用func的std :: bind生成的functor的operator()? 這是否被優化為與調用func(123)一樣最優的東西?

我不會將std::functionoperator()描述為'generated'(它是常規成員),但除此之外這是一個很好的描述。 優化取決於您的編譯器,但要注意優化std::function的間接(需要使用類型擦除),編譯器可能需要執行英雄。

構造函數在哪里生成std :: bind生成的? 在什么范圍? std :: bind如何命名呢? (可以有名稱沖突)

std::bind的調用返回一個未指定類型的仿函數,該仿函數的副本存儲在x對象中。 此副本將與x本身一樣長。 沒有名字涉及,所以我不確定你的意思。

lambda可以替換std :: bind的所有用法嗎?

不。考慮auto bound = std::bind(functor, _1); functor是一個帶有重載operator()的類型,讓我們說longint 然后bound(0L)bound(0)沒有相同的效果,你不能用lambda復制它。

std :: bind是否最適合將其作為lambda實現?

這取決於編譯器。 衡量自己。

怎么了std :: function的模板參數的語法? 如何解析它以及如何在其他地方使用該模板參數語法?

這是一種功能類型。 也許您已經熟悉指針/函數引用的語法: void(*)()int(&)(double) 然后只需刪除類型中的指針/引用,您只需要一個函數類型: void()int(double) 你可以使用這樣的:

typedef int* function_type(long);
function_type* p; // pointer to function

1。 x(123)實際上是否調用了生成std::function的functor的operator() ,而后者又調用了最終調用func std::bind生成的functor的operator() 這是否被優化為與調用func(123)一樣最優的東西?

如果你啟用了優化,那么'stuff'就會被內聯,你可以指望它與調用func(123)一樣最優。

2。 構造函數在哪里生成std::bind生成的? 在什么范圍? std::bind如何命名呢? (可以有名稱沖突)

精確: bind生成“轉瞬即逝”,實現定義,綁定表達式,可分配給function<> 功能只是一個類模板(謝謝,Luc T.)。 它存在於標准庫中。 但是,綁定表達式是實現定義的。

標准庫附帶的性狀( std::is_bind_expression<>以允許這樣的表達式的MPL檢測。 綁定表達式在std :: function上的一個決定性特征是它們(我稱之為) 延遲可調用對象 (即它們保留完整的調用站點語義,包括在實際應用程序站點選擇重載的能力)。 另一方面, std::function<>提交單個原型並通過類型擦除( 想象variantany )在內部存儲可調用對象

3。 lambda可以替換std :: bind的所有用法嗎?

4。 std :: bind是否最適合將其作為lambda實現?

AFAICT lambdas應該編譯為與綁定表達式大致相同。 有一件事我認為 lambdas不能做那個綁定表達式可以nested bind expressions 編輯雖然nested bind expressions的特定習慣用法不能使用lambdas復制,但lambdas當然能夠更自然地表達(幾乎)相同的內容:

 bind(f, bind(g, _1))(x); 
 // vs.
 [](int x) { f(g(x)); };

5。 怎么了std::function的模板參數的語法? 如何解析它以及如何在其他地方使用該模板參數語法?

它只是一個函數簽名(函數的類型 ),作為模板參數傳遞。

您還可以將它用作函數參數類型,它會降級為函數指針(類似於數組按值參數降級為指針的方式,感謝David!)。 在實踐中,大多數地方,只要您不需要命名變量/類型:

 void receiveFunction(void(int, double)); // spunky 'function<>'-style syntax

 void sample(int, double) { } 

 int main()
 { 
     receiveFunction(sample);
 }

 void receiveFunction(void (*f)(int, double)) // boring 'old' style syntax
 //                   void ( f)(int, double)  // ... also ok
 {
     // ..
 }

lambda可以替換std :: bind的所有用法嗎?

C ++ 14將允許lambdas主要替換bind。 特別回應Luc Danton的回答,在C ++ 14中,你可以使用auto編寫模板化的lambda,使得bound(0)bound(0L)表現不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM