我基于几个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_val
为nullptr
,则无法推断类型MinVal
。
选项2,我不确定如何使其仅返回smallest
或同时返回smallest
和min_val
。
我唯一能做的就是对函数定义两次-每种情况一次。这不是一个糟糕的选择,因为它很小—我只是想知道是否还有另一种方法。有吗?
我的建议?返回pair
。让呼叫者决定是否要使用最小投影值。您已经计算过了-对于不知道呼叫者意图的您来说,丢掉它是一种耻辱。