std::bind() 的函式簽名如下:
template< class F, class... Args >
/*unspecified*/ bind( F&& f, Args&& ... args ) 。
所以args是一個變體模板通用參考,如果我理解正確的話。傳統的通用參考的模板型別推導規則如下:
- 如果傳遞給T的引數是一個lvalue,那么T就被推導為一個lvalue參考 。
- 如果傳遞給T的引數是一個rvalue,那么T就被推導為一個lvalue 。
......我認為這些規則將單獨適用于args中的每個引數,這意味著所有傳遞到std::bind()的lvalues作為functor的引數將以參考方式傳遞。然而,這與下面的程式相矛盾:
void function(int& n) {
n ;
}
int main() {
int n = 0;
auto functor = std::bind(function, n)。
functor()。
std::cout << n << std::endl; //0,不是1.。
return 0。
}
為了讓n以參考的方式傳遞,你必須通過std::ref(n)明確地這樣做,鑒于我對通用參考和完美轉發的了解(很少),這真的讓我感到困惑。當std::bind()使用通用參考時,它是如何通過值來獲取任何東西的,否則它將消耗lvalues作為參考?
uj5u.com熱心網友回復:
這與簽名幾乎沒有關系,這是一個設計選擇。std::bind當然必須以某種方式存盤它的所有系結引數,它將它們存盤為值。這個 "普遍性 "只是用來正確地構造它們 - 通過移動或復制。
std::ref也是通過值來存盤的,但是由于其性質,被包裝的物件是通過參考來 "存盤 "的。
std::thread具有完全相同的行為。我們可以爭辯說,(移動)默認構建一個副本是更安全的,因為兩個回傳的物件都傾向于比最有可能被捕獲的本地物件要長。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316135.html
標籤:
上一篇:如何防止C 中的模板型別擴展?
