指定可绑定到函数模板的模板参数

时间:2015-02-04 20:26:51

标签: c++ templates c++11 variadic-templates

我正在尝试编写一个高阶函数,它将包含输入和输出迭代器的标准库函数。这是一次失败的尝试:

#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失败

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)

表达这个的正确方法是什么?而且,我理想的是能够简单地说出像

这样的东西
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...);
}

允许在想要遍历整个范围时避免指定迭代器。

2 个答案:

答案 0 :(得分:2)

您可以在this question/answer中找到有用的信息,但结果是您无法将功能模板作为模板(模板)参数传递,因此将std::for_each传递给方式是不可能的。

答案 1 :(得分:1)

您可以使用如here所示的包装类:

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

template<typename T, typename T2>
struct for_each_wrapper
{
    static T2 f(T ta, T tb, T2 t2)
    {
        return std::for_each(ta, tb, t2);
    }
};

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