2011-03-22 50 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

請記住,標準庫已經有一個良好開發和調試的優先級隊列,您可以使用任意比較函數。