2013-03-12 59 views
1

這裏是我的代碼的簡化版本:如何在<更改爲>時優雅地避免重複代碼?

template<typename TIterator> 
TIterator findMaximalPosition(TIterator begin, TIterator end) 
{ 
    TIterator result(begin); 
    for (TIterator it = begin + 1; it != end; ++it) 
    { 
     if ((*it)->value > (*result)->value) // Here I just need to change to "<" 
      result = it;      // to get a findMinimalPosition 
    } 
    return result; 
} 

template<typename TIterator> 
TIterator findMinimalPosition(TIterator begin, TIterator end) 
{ 
    // almost the same 
} 

這只是一個簡單的例子。我的代碼充滿了兩個功能相同的地方,除了<>符號或是否應使用++--

我的問題是:

有沒有一種方法,如何減少這種重複的代碼,而無需

  1. 銷燬可讀性
  2. 性能降低 ?

我正在考慮使用指向運算符的指針(<>)作爲模板參數。這不應該降低性能,因爲指針是一個編譯時間常量。有一些更好的或通常使用的方法嗎?

編輯:

基於答案所以我所做的就是實現:

template <typename TIterator, typename TComparison> 
TIterator findExtremalPosition(TIterator begin, TIterator end, 
           TComparison comparison); 

,然後只要致電:

return findExtremalPosition(begin, end, std::less<double>()); 

return findExtremalPosition(begin, end, std::greater<double>()); 

我希望這是你的eant。我想,在經過一番努力之後,類似的解決方案可以爲++--運營商完成。

+6

請參閱['max_element'](http://en.cppreference.com/w/cpp/algorithm/max_element)。 – 2013-03-12 15:16:57

+0

謝謝,但問題是我得到了這種情況很多,並且有些情況下標準算法不會完成這項工作。你是什​​麼意思的「==」? – 2013-03-12 15:18:31

+2

@MartinDrozdik:...仍然請參閱'max_element'。即使你不能使用它,它也能解決問題。 – 2013-03-12 15:30:38

回答

5

我會做,需要一個詞和使用std::greaterstd::less作爲參數傳遞給函數在給定類型分別實現findMaximalPositionfindMinimalPosition一般功能。

+2

正確的解決方案。函子通常比函數指針更高效,因爲它們是內聯的。 – MSalters 2013-03-12 15:28:31

+0

請注意,您仍然會有對象代碼重複。 – 2013-03-12 15:30:24

+2

@MSalters對於這樣的簡單事情,編譯器應該能夠使用指向函數的指針來內聯版本。 – 2013-03-12 15:32:05

1

Ivaylo Strandjev所示,一種可能的解決方案是使用謂詞。

所以,如果你改變你的函數,然後用謂詞來工作...

typename std::vector<int> vec; 

template<typename TIterator, bool (*Predicate)(const TIterator &, const TIterator &)> 
TIterator findPosition(TIterator begin, TIterator end) 
{ 
    TIterator result(begin); 
    for (TIterator it = begin + 1; it != end; ++it) 
    { 
     if (Predicate(it, result)) 
      result = it; 
    } 
    return result; 
} 

......而且,你定義一些謂詞,可以幫助你實現你的目標...

bool lesser(const vec::iterator &a, const vec::iterator &b) 
{ 
    return (*a) < (*b); 
} 

bool greater(const vec::iterator &a, const vec::iterator &b) 
{ 
    return (*a) > (*b); 
} 

...那麼你就可以做到這一點:

vec::iterator min = findPosition<typename vec::iterator, lesser>(v.begin(), v.end()); 
vec::iterator max = findPosition<typename vec::iterator, greater>(v.begin(), v.end()); 

的優點是提供任何功能竟被你d發現是有用的,不僅的那些,以檢查是否一個元件比其它更大或更小:

bool weird(const vec::iterator &a, const vec::iterator &b) 
{ 
    return ((*a) | (*b)) & 0x4; 
} 

vec::iterator weird = findPosition<typename vec::iterator, weird>(v.begin(), v.end()); 

here

但是在做這些工作之前,請檢查Algorithms library是否已經完成了這項工作。

我認爲它看起來非常整齊和簡單。

希望它有幫助。

+0

通常謂詞不被當作模板參數,只是另一個參數。 – GManNickG 2013-03-12 15:39:34

+0

@GManNickG好點!現在你提到它了,我不知道爲什麼我將它用作參數模板:O. – 2013-03-12 15:44:41