Offensichtlich macht der Code, wie Sie gepostet, nicht viel Sinn, als sowieso p(*f)
oder p(*f, *d)
würde nicht kompilieren. Daher müssen Sie diese in zwei Vorlagen spalten, und dann können Sie die Anzahl der Argumente von Predicate
testen einen ziemlich einfachen SFINAE Ansatz:
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;
}
Verbrauch:
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);
Natürlich können Sie verwenden std::bind
zu vermeiden, Code-Duplizierung durch den Aufruf der ersten Version von der zweiten.
Ein weiterer Ansatz ist Code zu verwenden, ähnlich wie bei std::bind
überprüft, dass es bekam benötigte Anzahl von Argumenten:
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
Diese nur für echte Funktionen arbeitet, nicht lambdas, noch std::function
, obwohl einige wahrscheinlicher Vorlagenmagie kann es für die letzten beiden Kategorien arbeiten lassen.
Es ist nicht möglich, und wenn Sie genau hinsehen, um die Standard-Library-Funktionen ein Prädikat nehmen (zum Beispiel [die Standardbibliothek Algorithmus Funktionen] (http://en.cppreference.com/w/cpp/algorithm)) erhalten Sie Sehen Sie, dass keiner von ihnen diese Art von Funktionalität hat, stattdessen haben sie unterschiedliche Überladungen, wenn sie unterschiedliche Prädikate benötigen. –