功能開銷

std::function 會導致很大的開銷。因為 std::function 具有[value semantics] [1],所以它必須將給定的 callable 複製或移動到自身中。但由於它可以採用任意型別的 callable,因此它經常需要動態分配記憶體來執行此操作。

一些 function 實現具有所謂的小物件優化,其中小型別(如函式指標,成員指標或具有極少狀態的函子)將直接儲存在 function 物件中。但即便如此,只有在型別為 noexcept 移動構造時才有效。此外,C++標準並不要求所有實現都提供一個。

考慮以下:

//Header file
using MyPredicate = std::function<bool(const MyValue &, const MyValue &)>;

void SortMyContainer(MyContainer &C, const MyPredicate &pred);

//Source file
void SortMyContainer(MyContainer &C, const MyPredicate &pred)
{
    std::sort(C.begin(), C.end(), pred);
}

模板引數將是 SortMyContainer 的首選解決方案,但我們假設無論出於何種原因這都是不可能或不可取的。SortMyContainer 不需要將 pred 儲存在自己的呼叫之外。然而,如果賦予它的仿函式具有一些非平凡的大小,pred 可能會很好地分配記憶體。

function 分配記憶體,因為它需要複製/移動的東西; function 獲得它所給予的可呼叫權。但是 SortMyContainer 不需要擁有可呼叫的東西; 它只是引用它。所以在這裡使用 function 是過度的; 它可能是有效的,但它可能不是。

沒有標準庫函式型別僅引用可呼叫函式。因此,必須找到替代解決方案,或者你可以選擇承擔開銷。

此外,function 沒有有效的方法來控制物件的記憶體分配來自何處。是的,有采取 allocator 建構函式,但[許多實現不正確地實現他們…甚至根本 ] [2]。

Version >= C++ 17

採取 allocatorfunction 建構函式不再是型別的一部分。因此,無法管理分配。

呼叫 function 也比直接呼叫內容慢。由於任何 function 例項都可以保持任何可呼叫,因此通過 function 的呼叫必須是間接的。呼叫 function 的開銷是虛擬函式呼叫的順序。