返回arg_min和可选的min_val的算法

问题描述 投票:0回答:1

我基于几个STL算法制作了一个简单的arg min函数:

template<class ForwardIt, class UnaryOperation>
ForwardIt arg_min(ForwardIt first, ForwardIt last, UnaryOperation unary_op)
{
  if (first == last) return last; //we were passed an empty container

  ForwardIt smallest = first; // iterator to the element that results in 
                              // the smallest value returned by unary_op
  auto smallest_val = unary_op(*first); //the actual smallest value

  ++first;
  for (; first != last; ++first) {
    auto first_val = unary_op(*first);
    if (first_val < smallest_val) {    // if unary_op returns a smaller than our current smallest value,
      smallest = first;                // store the iterator to the arg
      smallest_val = first_val;        // and the value itself
    }
  }
  return smallest;
}

它的效果非常好。但是,我知道我会想要获得实际最小值以及产生该值的参数的时候到了。我可以通过UnaryOperation函数重新运行返回的参数,但这是次优的。

我猜有两种策略-1)传递一个指向该函数然后填充的值类型的指针,或者2)返回一个std :: pair。我不太喜欢这两个选项,因为返回由arg min元素生成的值应该是可选的。对于选项(1),我最初的想法是:

template<class ForwardIt, class UnaryOperation, class MinVal>
ForwardIt arg_min(ForwardIt first, ForwardIt last, UnaryOperation unary_op, MinVal* p_min_val = nullptr)
{
  if (first == last) return last;

  MinVal min_val;

  if(p_min_val == nullptr){
    p_min_val = &min_val;
  }

  ForwardIt smallest = first;
  *p_smallest_val = unary_op(*first);

  ++first;
  for (; first != last; ++first) {
    auto first_val = unary_op(*first);
    if (first_val < smallest_val) {
      smallest = first;
      *p_smallest_val = first_val;
    }
  }
  return smallest;
}

我认为这不会起作用,因为如果p_min_valnullptr,则无法推断类型MinVal

选项2,我不确定如何使其仅返回smallest或同时返回smallestmin_val

我唯一能做的就是对函数定义两次-每种情况一次。这不是一个糟糕的选择,因为它很小—我只是想知道是否还有另一种方法。有吗?

c++ c++14 c++17
1个回答
0
投票

我的建议?返回pair。让呼叫者决定是否要使用最小投影值。您已经计算过了-对于不知道呼叫者意图的您来说,丢掉它是一种耻辱。

© www.soinside.com 2019 - 2024. All rights reserved.