簡體   English   中英

如果給出顯式返回類型,則從 function 返回通用 lambda 表達式會導致編譯器警告

[英]Returning a generic lambda expression from a function causes compiler warnings if an explicit return type is given

我有一個 function 其返回類型是一個簡單的通用 lambda 表達式。 (此 function 返回的 lambda 最終作為參數傳遞給 STL 算法,如std::transform()std::accumulate() )

當 lambda 沒有顯式返回類型時,編譯器不會發出警告:

inline auto AccumulateInto() {
    return [](const auto& src, const auto& dst) {return dst + src; };
}

當 lambda 具有指定的顯式返回類型時:

inline auto AccumulateInto() {
    return [](const auto& src, const auto& dst) -> decltype(dst) {return dst + src; };
}

兩個編譯器都會發出這些類似的警告:

GCC :返回對臨時 [-Wreturn-local-addr] 的引用

MSVC :返回局部變量或臨時地址

是否應注意此警告,因為它表明該方法存在缺陷(可能的未定義行為?)並且應該重構? 還是它們是“噪音”?

我無法確定為什么顯式指定返回類型會導致返回的表達式是“臨時的”,而如果不是這樣的話。 請解釋一下,謝謝!

編輯(添加更多上下文):

使用auto arguments 到 lambda 的願望是srcdst可能是不同的類型(例如,一個是std::uint8_t ,一個是std::uint_16t ),但我希望返回的總是與dst參數相同的類型,無論src的類型如何。

關鍵是decltype(dst)auto const & (您可以將auto視為模板類型),因此 lambda 返回一個對常量 object 的引用(我重復:一個引用)。

問題是這是一個參考

dst + src

即:對臨時值的引用,即從操作dst + src創建的臨時 object ,當 lambda 結束執行時不再存在。

一個可能的解決方案:刪除-> decltype(dst)或將其更改為-> decltype(dst+src) ,因此您返回一個值,而不是引用。

另一種方法(在這種情況下需要更多的打字,但在更復雜的情況下可能更受歡迎)可以從decltype()返回的類型中刪除引用部分。

所以

-> std::remove_reference_t<decltype(dst)>

或者,正如 Jarod42 所建議的,也

-> std::decay_t<decltype(dst)>

如果dst的類型支持一元運算符+ (返回相同類型的dst ),另一個簡單的解決方案可以是

-> decltype(+dst)

這樣, +dst是一個表達式,而不是一個變量,所以decltype(+dst)不再是一個引用。

暫無
暫無

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

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