2013-03-12 64 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