如何声明对std算法的引用?

时间:2018-03-31 12:24:46

标签: c++ pointers reference

我正在尝试添加对std算法的引用。如何编辑我的代码以使其正常工作?

double f(const std::vector<double> &arr, bool maxElem)
{
    auto me = maxElem ? std::max_element : std::min_element;
    //...
    x = me(arr.begin(), arr.end());
    //...
}

2 个答案:

答案 0 :(得分:3)

像这样:

if (maxElem)
   return std::max_element(arr.begin(), arr.end());
else
   return std::min_element(arr.begin(), arr.end());

可能可能获得对您尝试使用的每个“算法”的模板特化的引用,但由于需要指定模板参数,因此它将是凌乱和冗长的,因此虚假的经济。它也可能带来性能损失(破坏内联性)。

f首先表现得如此有意义;尝试让你的函数做好一个事情。可以说,它们的底层语义不应该依赖于这样的论点。

答案 1 :(得分:3)

您的功能是模板功能,因此您必须指定模板参数。在这种情况下,使用std::vector您需要传递它们迭代器

另外,为了应对函数的不同潜在重载,我们应该将它们转换到我们需要的类型(thnx to @ChristianHackl)

double f(const std::vector<double> &arr, bool maxElem)
{
    // deduce the iterator parameter types
    using Iterator = decltype(arr.begin());

    // select the overload type
    using Overload = Iterator(*)(Iterator, Iterator);

    auto me = maxElem
        ? static_cast<Overload>(std::max_element<Iterator>)
        : static_cast<Overload>(std::min_element<Iterator>);

    // need to dereference this because `me` returns an iterator
    return *me(arr.begin(), arr.end());
}

另请注意,我取消引用来自me()的返回值,因为它是一个迭代器(如指针)。

当然,如果您的矢量为空,会取消引用无效位置,因此我建议您进行检查:

double f(const std::vector<double> &arr, bool maxElem)
{
    // Avoid Undefined Behavior
    if(arr.empty())
        throw std::runtime_error("empty vector not allowed");

    // deduce the parameter types
    using Iterator = decltype(arr.begin());

    // select the overload type
    using Overload = Iterator(*)(Iterator, Iterator);

    auto me = maxElem
        ? static_cast<Overload>(std::max_element<Iterator>)
        : static_cast<Overload>(std::min_element<Iterator>);

    // need to dereference this because `me` returns an iterator
    return *me(arr.begin(), arr.end());
}