如何为函数类型使用模板参数?

时间:2018-09-11 04:33:27

标签: c++ templates

我正在尝试实现一个distance(x,y,f)函数,该函数计算必须将f应用于x才能获得y的次数。

例如,如果f = square,则distance(2, 256, square) == 3

我在这里使用的C ++代码改编自Stepanov和McJones的《编程元素》:

DistanceType(F) distance(Domain(F) x, Domain(F) y, Square<int> f) {
    typedef DistanceType(F) N;
    // Precondition: y is reachable from x under f
    N n(0);
    while(x != y) {
        x = f(x);
        n += 1;
    }
    return n;
}

Domain(F)DistanceType(F)分别设为#define的地方

我决定对函数类型使用仿函数,并使其成为int函数模板层次结构:

Square<T>

当我尝试使用template<typename T> class Transformation { public: Transformation() {}; virtual T operator() (T x) = 0; }; template<typename T> class Square : public Transformation<T> { public: virtual T operator() (T x) { return x * x; } }; 函数时,它会起作用:

distance

Full gist here (compiles with g++)

我的问题:

如何使#include <iostream> using namespace std; int main() { int x = 2; int y = 256; Square<int> f = Square<int>(); int d = distance(x, y, f); cout << "the distance between " << x << " and " << y << " is " << d << endl; return 0; } 的类型成为模板参数?

我已经尝试过了:

f

并将呼叫更改为此:

template<typename F>
DistanceType(F) distance(Domain(F) x, Domain(F) y, F f) {
    typedef DistanceType(F) N;
    // Precondition: y is reachable from x under f
    N n(0);
    while(x != y) {
        x = f(x);
        n += 1;
    }
    return n;
}

但是,当我编译时,出现此错误:

typedef Square<int> F;
int d = distance<F>(x, y, f);

我不明白这个错误。为什么不能使用In file included from /usr/include/c++/5/bits/stl_algobase.h:65:0, from /usr/include/c++/5/bits/char_traits.h:39, from /usr/include/c++/5/ios:40, from /usr/include/c++/5/ostream:38, from /usr/include/c++/5/iostream:39, from transformations.cpp:35: /usr/include/c++/5/bits/stl_iterator_base_types.h: In instantiation of ‘struct std::iterator_traits<Square<int> >’: /usr/include/c++/5/bits/stl_iterator_base_funcs.h:114:5: required by substitution of ‘template<class _InputIterator> typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = Square<int>]’ transformations.cpp:42:32: required from here /usr/include/c++/5/bits/stl_iterator_base_types.h:168:53: error: no type named ‘iterator_category’ in ‘class Square<int>’ typedef typename _Iterator::iterator_category iterator_category; ^ /usr/include/c++/5/bits/stl_iterator_base_types.h:169:53: error: no type named ‘value_type’ in ‘class Square<int>’ typedef typename _Iterator::value_type value_type; ^ /usr/include/c++/5/bits/stl_iterator_base_types.h:170:53: error: no type named ‘difference_type’ in ‘class Square<int>’ typedef typename _Iterator::difference_type difference_type; ^ /usr/include/c++/5/bits/stl_iterator_base_types.h:171:53: error: no type named ‘pointer’ in ‘class Square<int>’ typedef typename _Iterator::pointer pointer; ^ /usr/include/c++/5/bits/stl_iterator_base_types.h:172:53: error: no type named ‘reference’ in ‘class Square<int>’ typedef typename _Iterator::reference reference; 作为模板参数?

1 个答案:

答案 0 :(得分:2)

为什么不只有两个模板参数?

template <typename T, typename F>
unsigned long distance(T x, T y, F f)
{
    unsigned long n = 0;
    while(x != y)
    {
        x = f(x);
        ++n;
    }
    return n;
}

这同样适用于函数指针...

仅接受的变体接受功能:

template <typename T>
unsigned long distance(T x, T y, T (f)(T));
相关问题