将类或函数作为模板参数

时间:2010-12-18 22:38:08

标签: c++ templates operator-overloading function-pointers

我不确定要搜索什么,所以我会尽量解释一下。在STL中,std::set被定义为

template <class Key, class Compare, class Allocator> class set;

来自http://cplusplus.com

比较:比较类:一个类,它接受与容器元素相同类型的两个参数并返回一个bool。表达式comp(a,b),其中comp是此比较类的对象,a和b是容器 [...] 的元素。这可以是实现函数调用操作符的类,也可以是指向函数 [...] 的指针。

我在谈论Compare模板参数。

因此,如果我要编写一个模板类,它有一个模板参数,它是一个实现函数调用操作符的类,我会写

template <class T, class Combine>
class MyClass
{
public:
    Combine func;
    MyClass()
    {
        func = Combine();
    }
    T do_it(T a, T b)
    {
        return func(a, b);
    }
};

class IntCombine
{
public:
    int operator () (int a, int b)
    {
        return a + b;
    }
};

//...
MyClass<int, IntCombine> ob;
ob.do_it(4, 5);

或者,如果我要写它,那么第二个模板参数是一个函数:

template <class T, T Combine(T, T)>
class MyClass
{
public:
    Combine func;
    MyClass()
    {
        func = Combine;
    }
    T do_it(T a, T b)
    {
        return func(a, b);
    }
};

int IntCombine(int a, int b)
{
    return a + b;
}

//...
MyClass<int, IntCombine> ob;
ob.do_it(4, 5);

但是,在STL中,您可以使用set class。这是如何实现的?上面的代码只有在我的ob定义中的第二个模板参数分别是实现operator ()的类或函数的情况下才有效,但我不能写MyClass以便两者都能正常工作。

我的例子可能看起来毫无用处。基本上我想编写一个可以组合元素的容器,它与STL容器一样通用。

1 个答案:

答案 0 :(得分:0)

  

上面的代码只有在我的ob定义中的第二个模板参数分别是一个实现operator()或一个函数的类时才有效,但我不能编写MyClass以便两者都可以工作。

是的,你可以:

template <typename F>
struct foo {
    F f;
    void call() {
        f();
    }
};

void function() {
    std::cout << "function called" << std::endl;
}

int main() {
    foo<void(*)()> a = { function };
    a.call();
}

这完全遵循example of the std::set constructor。重要的一点是,如果你使用的是函数指针,那么模板参数不是那个函数指针,它是函数指针的类型(这里是{{1} })。您需要单独存储实际的函数指针。