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>());

我希望这就是你的意思。++我想经过一番苦苦挣扎后,可以为--运营商完成类似的解决方案。

4

2 回答 2

5

我将创建一个通用函数,该函数接受谓词并使用std::greaterstd::less作为该函数的参数,以分别实现给定类型findMaximalPositionfindMinimalPosition

于 2013-03-12T15:16:02.723 回答
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());

优点是提供您认为有用的任何功能,而不仅仅是检查元素是否大于或小于其他元素的功能:

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());

这里的例子。

但在做这项工作之前,请检查算法库是否已经完成了这项工作。

我认为它看起来非常整洁和简单。

希望能帮助到你。

于 2013-03-12T15:38:39.667 回答