如何以" auto"的值返回?返回类型功能

时间:2014-03-02 08:25:54

标签: c++ visual-c++ c++11

好的,我不知道我是否用标题解释得很好,所以我只想举个例子。我试图找到一个函数,找到一系列浮点数的中位数(还有一点额外的)。这是功能:

    //get the median of an unordered set of numbers of arbitrary type without modifying the
    //underlying dataset
    template <typename InputIterator>
    auto Median(
        InputIterator const cbegin, 
        InputIterator const cend,
        bool const abs = false // get the median of the absolute values rather than nominal values
        ) -> decltype(*cbegin)
    {
        typedef std::iterator_traits<InputIterator>::value_type T;

        std::vector<T> data;
        data.reserve(std::distance(cbegin, cend));

        // get a copy of the values for sorting
        for (InputIterator it = cbegin; it != cend; ++it)
        {
            if (abs)
                data.push_back(std::abs(*it));
            else
                data.push_back(*it);
        }

        // find the median
        std::nth_element(data.begin(), data.begin() + data.size() / 2, data.end());

        return data[data.size() / 2];
    }

如果我尝试编译它,这是输出:

  

警告C4172:返回本地变量的地址或临时

我已尝试将decltype(*cbegin)替换为std::remove_reference<decltype(*cbegin)>::typestd::iterator_traits<decltype(*cbegin)>::value_type,但这些也不会编译。

有一个简单的解决方案吗?如何返回InputIterator点的类型?

编辑:这是基于反馈的固定版本:

    //get the median of an unordered set of numbers of arbitrary type without modifying the
    //underlying dataset
    template <typename RandomAccessIterator>
    typename std::iterator_traits<RandomAccessIterator>::value_type Median(
        RandomAccessIterator const cbegin,
        RandomAccessIterator const cend,
        bool const abs = false // get the median of the absolute values rather than nominal values
        )
    {
        typedef std::iterator_traits<RandomAccessIterator>::value_type T;

        std::vector<T> data(cbegin, cend);

        // find the median
        std::nth_element(data.begin(), data.begin() + data.size() / 2, data.end(),
            [abs](T const a, T const b)
        {
            return abs ? std::abs(b) > std::abs(a) : b > a;
        });

        return data[data.size() / 2];
    }

2 个答案:

答案 0 :(得分:3)

您可以将iterator_traits与模板参数一起使用,不需要decltype:

template <typename InputIterator>
typename std::iterator_traits<InputIterator>::value_type
Median(
    InputIterator const cbegin, 
    InputIterator const cend,
    bool const abs = false
);

请注意typename关键字 - 这是您尝试中遗漏的内容。

答案 1 :(得分:2)

编译器告诉你,你正在返回一些临时的东西,实际上,你是。

decltype(* cbegin)是一个引用(所以你可以编写像*it = 12这样的代码),所以你要返回data中临时的某个值的引用。

您可以使用std::remove_reference<decltype(*cbegin)>::type

删除引用