2011-03-22 49 views
4

您可以在C++中使用模板(或类似的)来指定在一个函数中完成哪个操作?由操作员填充的模板

我不知道该怎么解释得清楚,所以我会告诉你怎么可能是(但不)在代码中完成:

template <operator OPERATION> int getMaxOrMin(int a, int b) { 
    return a OPERATION b ? a : b; 
} 

哪里找到最大或最小的a或b。将(这是我的伪语法变得有点混乱,多多包涵):

int max = getMaxOrMin< > > (a, b); 
int min = getMaxOrMin< < > (a, b); 

我知道这不是如何做到这一点在所有的(因为它甚至不语法使感觉),但我希望澄清我想要做的事情的类型。

我想知道这是我正在做一个PriorityQueue实现,并且它很好很容易切换后备是一个最大堆或一个小堆在飞行中而无需复制和粘贴代码两个不同的类。

我知道我可以用宏做到这一点,但唯一的方法我知道如何做到这一点会给我一个最大堆或最小堆,但不是在同一编译中。不过,我可能忽略了一种方式。

+0

你可以做一个基类和具有最大堆/最小堆作为子类,然后让getMaxorMin功能在基类中是虚拟的,并且在max-heap/min-heap中以不同的方式实现它。 – Grammin 2011-03-22 17:03:42

回答

2

是的,但你需要定义它像一个函子:

template <typename OPERATION> 
int getMaxOrMin(int a, int b) 
{ 
    OPERATION operation; 
    return operation(a, b) ? a : b; 
} 

现在你可以使用这样的:

struct myLess 
{ 
    bool operator()(int a,int b) const { return a < b; } 
} 
struct myGreat 
{ 
    bool operator()(int a,int b) const { return a > b; } 
} 

void code() 
{ 
    int x = getMaxOrMin<myLess>(5,6); 
    int y = getMaxOrMin<myGreat>(5,6); 
} 

这似乎是一个大量的工作。但是标准中有很多预定义的函子。在this page向下滚动到“6:功能对象”。
对于您的情况有:

std::less 
std::greater 

因此,代码变为:

template <typename OPERATION> 
int getMaxOrMin(int a, int b) 
{ 
    OPERATION operation; 
    return operation(a, b) ? a : b; 
} 

void codeTry2() 
{ 
    int x = getMaxOrMin<std::less<int> >(5,6); 
    int y = getMaxOrMin<std::greater<int> >(5,6); 
} 
+0

最后的代码片段不正确,'std :: less'和'std :: greater'是模板,你想要使用的是该模板的具体实例:'getMaxOrMin >(5, 6)'。另外,当使用函数模板(而不是类模板)时,函子通常(作为值)作为第三个参数传递,而不是作为需要在内部构造的类型参数:'template int getMaxOrMin(int a ,int b,Functor f);'并用作'getMaxOrMin(a,b,std :: less ());'除了与STL的一致性,我没有理由这样做。 – 2011-03-22 17:42:45

+0

修正std:less等在这种情况下,我认为传递函子作为第三个参数不会添加任何东西(实际上会降低可读性)。但是,这一切都是上下文敏感的,读者应该使用适合情况的内容。 – 2011-03-22 17:53:03

+0

非常感谢,这是非常丰富和有用的。 – Carrotman42 2011-03-22 18:59:44

8

做什么std::map和朋友做:以一个比较函数/仿函数作为您的模板参数。见std::lessstd::greater

请记住,标准库已经有一个良好开发和调试的优先级队列,您可以使用任意比较函数。