我假定不排除C++ 11解決方案。
我也會假設OP是正確的,相信他希望 檢測到具有簽名bool(int &)
的函數或函子。使用 std::function
,如由Dave建議:
void foo(const std::function<bool(int&)>& f);
將確實確保作爲f
可接受任何參數包含 一元函數狀對象,其參數是一個類型的那 可以結合int&
並且其返回類型可隱式轉換爲 至bool
。但是:
double bar(bool b) {
return b ? DBL_MAX : DBL_MIN;
}
是這樣一個對象,它似乎牽強估計它是「可調用對象 將參考爲int並返回一個布爾值。」
,我們希望測試函數和類的對象 意味着在靜脈SFINAE類模板的事實:
template<typename T>
struct is_predicate_of_ref_to_int_type { ... };
將不太受itelf符合這個要求,因爲儘管我們可以實例與 typename T
一個仿函數類型,我們不能用typename T
函數實例化。
對於功能func
我們應該實例化與T
= decltype(func)
; 但不對稱仍然存在,因爲對於函數類型Functor
我們不能 實例化與T
= decltype(Functor)
,因爲Functor
不是一個表達式。
這樣的SFINAE類模板將成爲我們一旦獲得 問題的對象類型的目的,而是要走到這一步具有均勻 成語,我們可以使用一個重載函數,其參數也可以同樣 是函數或函子對象。這裏是這樣的解決方案,具有附加的測試程序 :
#include <type_traits>
template<class T>
struct is_predicate_of_ref_to_int_type {
// SFINAE operator-has-correct-sig- :)
template<class A>
static auto test(bool (A::*)(int &)) -> std::true_type;
// SFINAE operator-exists :)
template <class A>
static auto test(decltype(&A::operator()),void *) ->
// So the operator exists. Has it the correct sig?
decltype(test(&A::operator()));
// SFINAE failure :(
template<class A>
static auto test(...) -> std::false_type;
// This will be either `std::true_type` or `std::false_type`
typedef decltype(test<T>(0,0)) type;
static const bool value = type::value;
};
template<typename T>
bool is_predicate_of_ref_to_int(T const & t) {
return is_predicate_of_ref_to_int_type<T>::value;
}
bool is_predicate_of_ref_to_int(bool (function)(int &)) {
return true;
}
// Testing...
struct passing_class_0
{
bool operator()(int & i) {
return i > 0;
}
};
struct failing_class_0
{
bool operator()(int i) {
return i > 0;
}
};
struct failing_class_1
{
bool operator()(int & i, int & j) {
return i > j;
}
}
struct failing_class_2{};
bool passing_function_0(int & i) {
return i > 0;
}
bool failing_function_0(int i) {
return i > 0;
}
int failing_function_1(int & i) {
return i;
}
void failing_function_2(){}
#include <iostream>
using namespace std;
int main()
{
passing_class_0 pc0;
failing_class_0 fc0;
failing_class_1 fc1;
failing_class_2 fc2;
cout << "Expecting pass..." << endl;
cout << is_predicate_of_ref_to_int(pc0) << endl;
cout << is_predicate_of_ref_to_int(passing_function_0) << endl;
cout << "Expecting fail..." << endl;
cout << is_predicate_of_ref_to_int(fc0) << endl;
cout << is_predicate_of_ref_to_int(fc1) << endl;
cout << is_predicate_of_ref_to_int(fc2) << endl;
cout << is_predicate_of_ref_to_int(failing_function_0) << endl;
cout << is_predicate_of_ref_to_int(failing_function_1) << endl;
cout << is_predicate_of_ref_to_int(failing_function_2) << endl;
cout << is_predicate_of_ref_to_int(failing_function_2) << endl;
cout << is_predicate_of_ref_to_int(1L) << endl;
return 0;
}
內置與GCC 4.7.2或鐺3.2,這具有預期的輸出。
有一個警告。過載operator()
的任何函子類型將失敗 測試,例如,
struct bar
{
bool operator()(int & i) { ... }
bool operator()(int & i, int & j) { ... }
};
即使重載之一是令人滿意的,由於在服用重載成員函數的地址的標準的 限制。
您是否有可用的C++ 11編譯器?你可以使用boost類型特徵庫嗎? –
你想區分'other :: operator()'和'bar()'嗎?或者你只是想知道'functor f'是否是'bool(int&)'類型? – iammilind
你的意思是這樣的:http://ideone.com/22Llh(從維基百科複製和破解)? – Vlad