簡體   English   中英

為什么C ++ 17的std :: any不允許any_cast返回一個可移動的值?

[英]Why does C++17's std::any not allow returning a movable value by any_cast?

根據本Wiki中提供的規范實現C ++ 17的std::any ,我偶然發現了一些對我來說似乎荒謬的事情:

自由函數std::any_cast 的定義中,它用於從std::any實例中檢索值,提供了r值引用的重載(它是第三個):

template< class ValueType >
ValueType any_cast(any&& operand); // (3)

現在,在概要下面列出的要求適用於重載2和3(這也意味着包括r值重載):

2-3)返回*any_cast<std::remove_reference_t<ValueType>>(&operand)

該定義似乎實際上不允許移動數據!

函數調用只是重定向到基於指針的重載; 有關operand暫時性質的信息丟失了!

是不是我不能離開任何一個實例? 這只是維基中的一個錯誤嗎? 我錯了嗎?

在撰寫本文時,問題出現在WP狀態, 這意味着

WP - (工作文件) - 提議的決議尚未被接受為技術勘誤,但WG21 / PL22.16的完整委員會已投票決定將缺陷報告的擬議決議應用於工作文件。

有關詳細信息,請參閱lwg: http ://wg21.cmeerw.net/lwg/issue2509

確實提出了一項決議案

對於第三種形式,如果is_move_constructible_v<ValueType>為true且is_lvalue_reference_v<ValueType>為false,則為std::move(*any_cast<remove_reference_t<ValueType>>(&operand)) ,否則為*any_cast<remove_reference_t<ValueType>>(&operand)

以及列出WP的缺陷報告列表: http//cplusplus.github.io/LWG/lwg-defects.html#2509

完全可以執行不需要復制的std::any 只有一個問題:當用戶請求std::any的副本時你會怎么做? 這個問題的一個解決方案是使std::any move-only,另一個是使它在復制構造函數上拋出一個異常,如果底層類型是只移動的,另一個是要求能夠復制底層類型。 選擇了第三種解決方案。

對可復制構造的ValueType的要求非常好 - 因為不能復制構造的類型不可能存儲在std::any實例中, std::any_cast也可能使一個總是失敗的構建編譯器錯誤。

現在, ValueType any_cast(any&& operand)實現不允許移動似乎是一個疏忽 - 畢竟,副本是一個完美的移動實現,並且實現可以自由地將作業委托給移動構造函數,如果它在那里,並復制構造函數,如果沒有。

暫無
暫無

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

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