[英]Using std::any_cast with decltype ... why does this code throw a bad 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.