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



在 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 { 
};

您可以简单地使用非类型模板参数:

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;

在 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方法将执行传递的 in 函数并返回其返回值:

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

在上面的类中,模板参数现在是一个函数类型,并且成员函数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;
}

最新更新