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