考慮下面的類:是否可以根據方法簽名中是否存在某個參數來將模板專門化?
class MyClass
{
public:
template<class T> typename T::result_type apply(T& func)
{
if (is_int())
{
return func(int(0));
}
return func(double(0));
}
...
};
(代碼看起來不是非常有用的,但它只是一個人爲的樣本來證明我的觀點)
無論如何,一個典型的仿函數將是這樣的:
struct MyFunc
{
typedef void result_type;
template<class V> void operator()(V)
{
// do something
}
};
而且人會使用它,像這樣:
MyClass c;
MyFunc f;
c.apply(f);
我的問題是 - 可以將MyClass::apply
改爲識別功能函數的一個稍微不同的版本,除了原來的一個,例如期望調用者對象引用與所有其他參數一起傳遞這樣的:
struct MyFuncEx
{
typedef void result_type;
template<class V> void operator()(const MyClass& caller, V)
{
// do something
}
};
所以,下面的代碼將編譯過:
MyClass c;
MyFunc f;
c.apply(f);
MyFuncEx f2;
c.apply(f2);
作爲獎勵,我想編譯如果函子同時包含超載,失敗也就是下面要失敗編譯:
struct MyFuncSmartAss
{
typedef void result_type;
template<class V> void operator()(V)
{
// do something
}
template<class V> void operator()(const MyClass& caller, V)
{
// do something
}
};
...
MyClass c;
c.apply(MyFuncSmartAss());
但是,只要較長的重載佔優先於較短的重載並不重要。
的boost :: bind()的是你的朋友 –
而且??????????? – mark
有了boost :: bind,你可以承受一個'operator()'的重載,並決定調用網站在'caller'上創建一個閉包來提供一個'operator()',即使在第二個案件。 –