mercredi 4 février 2015

Specify a template argument which could bind to a function template

I am trying to write a higher-order function which would wrap around the standard library functions taking input and output iterators. Here's a failed attempt:



#include <algorithm>
#include <iostream>
#include <type_traits>
#include <vector>
using namespace std;

template <template <typename, typename> class Func, typename InpIt, typename UnaryFunction>
decltype(Func<InpIt, UnaryFunction>(declval<InpIt>(), declval<InpIt>(), declval<UnaryFunction>())) Apply(InpIt first, InpIt last, UnaryFunction f)
{
return Func<InpIt, UnaryFunction>(first, last, f);
}

int main()
{
vector<int> a(5);
Apply<for_each>(a.begin(),
a.end(),
[](int i)
{
cout << i << endl;
});
return 0;
}


Clang 3.5 fails with



high.cpp:16:3: error: no matching function for call to 'Apply'
Apply<for_each>(a.begin(),
^~~~~~~~~~~~~~~
high.cpp:8:100: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Func'
decltype(Func<InpIt, UnaryFunction>(declval<InpIt>(), declval<InpIt>(), declval<UnaryFunction>())) Apply(InpIt first, InpIt last, UnaryFunction f)


What is the right way to express this? Also, what I would ideally want is to be able to simply say something like



template <MagicIncantation Func, typename Range, typename ... Args>
MoreMagic Apply(Range&& rng, Args&& ... args)
{
using std::begin; using std::end;
Func(begin(rng), end(rng), args...);
}

Aucun commentaire:

Enregistrer un commentaire