簡體   English   中英

使用std :: greater或std :: less作為參數的參數

[英]Parameter to use std::greater or std::less as argument

我想用一個接受std::greater<int>std::less<int>作為參數的參數創建一個函數。 不過,我仍然堅持參數的語法。

這是我嘗試的格式:

myFunction(int a, int b, bool *comp(int, int)) { … }
…
std::greater<int> bigger;
myFunction(2, 3, bigger);

但這不起作用,我懷疑第三個參數完全錯誤。 它到底應該是什么?

無法將std::greater<int>轉換為bool* (*)(int, int)

采用比較器的函數通常通過模板實現:

template <typename Comparator>
myFunction(int a, int b, Comparator comp) { … }

但你也可以使用std::function來實現它:

myFunction(int a, int b, std::function<bool (int, int)> ) { … }

第一個版本公開了標題中的代碼,但通常會表現得更好。 對於第二個版本,您可以隱藏.cpp文件中的實現,但由於無法內聯比較器調用,您將失去一些性能。

所以這里的技巧是std::lessstd::greater實際上是無狀態函數對象,可以簡單地構造。 但是它們不支持轉換為函數指針。

有效的選擇是(A)通過template參數獲取比較器並在頭中實現代碼:

template<typename C> void myFunc( int a, int b, C comp )

這意味着你必須在頭文件中實現它,或者(B)通過std::function< bool(int, int) >鍵入擦除函數對象:

void myFunc( int a, int b, std::function< bool(int, int) > comp )

這有一些成本(可能很重要?Profile!)(通過對無狀態std less / greater的小對象優化來避免堆分配,但無論如何都會花費virtual函數調用,這也會阻止內聯)。

或者(C)編寫一些代碼,讓您使用無狀態仿函數並將其轉換為函數指針:

template<typename T>
using Type = T;
template<typename StatelessFunctor>
struct function_ptr_of_stateless_t {
  template<typename R, typename... Args>
  operator Type<R(Args...)>*() const {
    return [](Args... args)->R {
     return StatelessFunctor()(std::forward<Args>(args)...);
    };
  }
};
template<typename StatelessFunctor>
function_ptr_of_stateless_t<StatelessFunctor> as_function_ptr() {
  return {};
}

bool myFunction( int a, int b, bool(*comp)(int, int) ) { return comp(a,b); }
int main() {
  std::cout << myFunction(3,7, as_function_ptr<std::less<int>>() ) << "\n";
}

其中template函數as_function_ptr采用無狀態as_function_ptr函數的類型,並創建一個拋棄類型,允許您將其轉換為任何兼容的函數指針類型。

這比std::function解決方案的開銷要小得多,因為對函數指針的調用往往比virtual方法更快,而且一些編譯器(如gcc)在內聯函數指針方面相當不錯,即使從一個編譯單元到另一個。

作為獎勵,在C ++ 14中你可以使用:

int main() {
  std::cout << myFunction(3,7, as_function_ptr<std::less<>>() ) << "\n";
}

它仍然可以很好地工作。

使用模板:

template<class Callable>
myFunction(int a, int b, Callable f);

暫無
暫無

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

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