Having class or function as template parameter

百般思念 提交于 2019-12-10 18:06:03

问题


I wasn't sure what to search for, so I'll try to explain as best as possible. In the STL, std::set is defined as

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

From http://cplusplus.com:

Compare: Comparison class: A class that takes two arguments of the same type as the container elements and returns a bool. The expression comp(a,b), where comp is an object of this comparison class and a and b are elements of the container [...]. This can either be a class implementing a function call operator or a pointer to a function [...].

I am talking about the Compare template parameter.

So if I were to write a template class, that has a template parameter which is a class implementing a function call operator, I'd write

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);

Or, if I were to write it so the second template parameter is a function:

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);

However, in the STL you can use the set class either way. How is this realised? The above code works only if the second template parameter in my definition of ob is either a class implementing operator () or a function, respectively, but I cannot write MyClass so that both will work.

My examples may look fairly useless. Basically I want to write a container that can combine elements, and that is as generic as the STL containers.


回答1:


The above code works only if the second template parameter in my definition of ob is either a class implementing operator () or a function, respectively, but I cannot write MyClass so that both will work.

Yes you can:

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();
}

This is exactly following the example of the std::set constructor. The important point is that if you’re using a function pointer, the template parameter is not that function pointer, it’s the type of the function pointer (here void (*)()). You need to store the actual function pointer separately.



来源:https://stackoverflow.com/questions/4480547/having-class-or-function-as-template-parameter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!