簡體   English   中英

如何按值返回“自動”返回類型函數

[英]How do I return by value for an “auto” return type function

好的,我不知道我對標題的解釋是否很好,所以我只舉一個例子。 我試圖提出一個函數,該函數可以找到一系列浮點數的中位數(還有一些額外的值)。 這是函數:

    //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];
    }

您可以將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關鍵字-這是您嘗試中缺少的內容。

編譯器告訴您,您實際上正在返回一些臨時信息。

decltype(* cbegin)是一個引用(因此您可以編寫*it = 12類的代碼),因此您將返回對data內部臨時值的引用。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM