投稿したコードは明らかに意味がありません。とにかくp(*f)
またはp(*f, *d)
のいずれもコンパイルに失敗します。したがって、あなたは、2つのテンプレートにこれを分割し、その後、あなたはかなり単純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
を使用して、2番目のバージョンから最初のバージョンを呼び出すことによってコードの重複を回避します。
別のアプローチには、引数の必要数得たことをどのように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
これは実関数ではなく、ラムダのためにのみ動作し、またstd::function
を、テンプレートマジックは、後者の2つのカテゴリでうまく機能させることができます。
標準ライブラリ関数(たとえば[標準ライブラリアルゴリズム関数](http://en.cppreference.com/w/cpp/algorithm))を使って標準ライブラリ関数を詳しく見てみると、そのような機能を持っていないことを確認してください。代わりに、異なる述語が必要な場合は、異なるオーバーロードがあります。 –