繁体   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