很明顯,您發佈的代碼沒有多大意義,因爲無論如何,p(*f)
或p(*f, *d)
都無法編譯。因此,你需要把這個分成兩個模板,然後你可以使用一個相當簡單的SFINAE方法測試的Predicate
參數的個數:
template <class InputIterator, class Predicate>
bool visitAll(InputIterator f, InputIterator l, Predicate p, UserData* d=nullptr,
decltype(declval<Predicate>()(*declval<InputIterator>()),1) unused = 1)
{
cout << "1" << std::endl;
for(; f != l; ++f)
{
if(!p(*f))
return false;
}
return true;
}
template <class InputIterator, class Predicate>
bool visitAll(InputIterator f, InputIterator l, Predicate p, UserData* d=nullptr,
decltype(declval<Predicate>()(*declval<InputIterator>(), declval<UserData>()),1) unused = 1)
{
cout << "2" << std::endl;
for(; f != l; ++f)
{
if(!p(*f, *d))
return false;
}
return true;
}
用法:
std::vector<int> a{1,2};
const auto t = [](int x){ return 1;};
const auto t2 = [](int x, UserData y){ return 1;};
UserData d;
visitAll(a.begin(), a.end(), t);
visitAll(a.begin(), a.end(), t2, &d);
當然,你可以使用std::bind
通過從第二個版本調用第一個版本來避免代碼重複。
另一種方法是使用相似的代碼如何std::bind
檢查它是否得到了需要的參數個數:
template<typename _Func>
struct noa_helper {
};
template<typename _Ret, typename... _Args>
struct noa_helper<_Ret (*)(_Args...)> {
static int noa() { return sizeof...(_Args); }
};
template<class F>
int number_of_arguments(F f) {
return noa_helper<typename std::decay<F>::type>::noa();
}
void foo();
int bar(int x, int y);
...
std::cout << number_of_arguments(foo) << std::endl; // prints 0
std::cout << number_of_arguments(bar) << std::endl; // prints 2
這僅適用於真正的功能,而不是lambda表達式,也不std::function
,雖然可能更多一些模板魔法可以使它適用於後兩類。
這是不可能的,並且如果仔細觀察採用謂詞的標準庫函數(例如[標準庫算法函數](http://en.cppreference.com/w/cpp/algorithm)),您將看到他們都沒有這種功能,如果他們需要不同的謂詞,他們會有不同的重載。 –