如何在C ++模板中声明函数delaration

时间:2018-04-13 11:47:13

标签: c++ templates ada template-meta-programming generic-programming

在Ada中,我可以定义以下通用(等效于C ++模板):

Generic
With function Sum( .. ) return boolean
Package XXXX is ……
End package

以后可以将泛型实例化如下

Package XXXX_1 is new XXXX( Sum => Sum_Int );

换句话说,我可以创建一个Ada泛型包,它需要一个函数来实例化它,现在我该如何在C ++中执行此操作?即

template < *function_declaration* >
    class Stack { 
    };

2 个答案:

答案 0 :(得分:2)

您只需使用非类型模板参数:

template <bool (*)(int, int> class PriorityQueue { };

// Instantiate:
PriorityQueue<&std::less<int>::operator()> myStack;

不幸的是,你在这里看到的是int<int实际上并不是C ++中的函数,而是内置函数。因此,我们需要std::less<int>包装器。将函数包装在类型中是很常见的,正是因为这个:

template <typename Order = std::less<int>> 
class PriorityQueue;

// Instantiate, override default
PriorityQueue<std::greater<int>> myStack;

答案 1 :(得分:1)

在c ++中,您可以使用运行时多态来实现此目的,即定义抽象基类并从中派生具体类。 例如,在XXXX类中,将Sum方法声明为纯虚拟,并且从中继承的每个类都必须实现该方法(否则它们也保持抽象):

基类:

class XXXX
{
public:
    virtual ~XXXX() = default;
    virtual bool Sum() = 0; //this has to be overridden
};

派生类:

class XXXX_1 : public XXXX
{
public:
    bool Sum() override
    {
        // Sum implementation here
    }
};

Sum实现特定于XXXX_1类。您可以拥有更多实现,但每个实现都需要一个不同的类(派生自XXXX)。

更复杂的模式,根本不涉及多态:

typedef bool (*_Sum)(); // _Sum is now a function type

class XXXX
{
    _Sum _sum;
public:
    XXXX(_Sum s) : _sum(s){}

    bool Sum()
    {
        if(_sum != nullptr)
        {
            return _sum();
        }
        return false; //just a default
    }
};

实例化上面的类时,函数指针在构造中传递,Sum方法将执行传入的函数并返回其返回值:

bool f() //this function matches the _Sum type defined above
{
    return false;
}

int main(int argc, char *argv[])
{

    XXXX xxxx(f); //we're passing a pointer to f function, here
    xxxx.Sum(); //execute f

    return 0;
}

使用模板,事情可以变得更加通用:

template <typename F>
class XXXX
{
    F _f;
public:
    XXXX(F f) : _f(f){}
    bool f()
    {
        return _f();
    }
};

在上面的类中,template参数现在是一个函数类型,成员函数f具有相同的返回类型。

我们可以将上面定义的_Sum函数类型作为F传递,并且(在构造中)传递指向上面定义的函数f的指针:

int main(int argc, char *argv[])
{
    XXXX<_Sum> xxxx(f);
    xxxx.f(); //execute f again
    return 0;
}

或任何类型的任何函数:

#include <iostream>

typedef void (*_Void)(); //another function type

void v(){ std::cout << "Hello" << std::endl; }

int main(int argc, char *argv[])
{
    XXXX<_Void> xxxx(v);
    xxxx.f();
    return 0;
}