[英]C++ how to pass method as a template argument
假設我有一個X
類:
class X {
// ...
size_t hash() const { return ...; }
};
我想創建一個std::tr1::unordered_map<X, int, HashFn>
,我想在X::hash()
中HashFn
。 我知道我可以聲明自己的仿函數對象。 我覺得應該有辦法通過直接傳遞一個指向X::hash()
的指針來實現這一點。
在那兒?
不,沒有。 原因是無論用作HashFn的是什么,都必須使用一個參數,該參數是對容器中對象的const引用。 X::hash
接受一個參數,它是一個指向容器中對象的const 指針 (在這種情況下this
指針是一個隱式的第一個參數),因此不能使用該函數。
你可能使用一些綁定魔法,使用boost :: lambda和boost :: bind。 我不確定如何,但它可能看起來像這樣:
boost::bind(&X::hash, &_1);
這創建了一個函數對象,它將使用指針調用X :: hash。
沒有; 如你所示,你需要一個小的實用程序結構:
#include <functional>
template<typename T, std::size_t (T::*HashFunc)() const = &T::hash>
struct hasher : std::unary_function<T, std::size_t>
{
std::size_t operator ()(T const& t) const
{
return (t.*HashFunc)();
}
};
然后你可以像這樣創建一個unordered_map
:
std::tr1::unordered_map<X, int, hasher<X> > m;
size_t hash() const { return ...;}
計算哈希值的函數采用Key
函數不帶的一個Key
類型的參數。 因此,它的簽名開始時是錯誤的。
既然你想要實現一個函數,而不是一個函子,那么應該如何實現:
size_t hash(const KeyType &key)
{
return /*calculate hash and return it*/;
}
使它成為static
成員函數並將其作為X::hash
傳遞或使其成為自由函數,是您的選擇。
你不能直接,但你可以包裝它。 這樣做的簡單方法是使用boost::mem_fn()
,或者如果你的編譯器支持它們的標准等價物: tr1::mem_fn()
(來自TR1)或std::mem_fn()
(來自C ++ 11) 。
編輯:其實不是那么簡單。 mem_fn()
適用於函數參數,但由於其返回類型未指定,因此很難用作模板參數。 如果你有C ++ 11支持,你可以使用decltype
來查找類型; 否則你最好自己編寫自己的函數對象,就像你提到的那樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.