为什么 C++17 的 std::any 不允许 any_cast 返回一个可移动的值?
Why does C++17's std::any not allow returning a movable value by any_cast?
在根据可用规范 in this Wiki 实现 C++17 的 std::any
时,我偶然发现了一些对我来说似乎荒谬的东西:
自由函数 std::any_cast
的 In the definition,用于从 std::any
实例中检索值,r-value[=38= 的重载] 提供参考文献(这是第三个):
template< class ValueType >
ValueType any_cast(any&& operand); // (3)
现在,概要下方列出了适用于重载 2 和 3 的要求(这意味着还包括右值重载):
2-3)
Returns *any_cast<std::remove_reference_t<ValueType>>(&operand)
定义似乎实际上不允许移动数据!
函数调用只是重定向到基于指针的重载;有关 operand
临时性质的信息丢失了!
是不是有意让我不能搬出any实例?这只是维基中的一个错误吗?我错了吗?
不需要复制的std::any
实现是完全可以做到的。只有一个问题:当用户请求 std::any
的副本时,你会怎么做?这个问题的一个解决方案是让 std::any
只移动,另一个是如果底层类型是只移动,让它在复制构造函数上抛出异常,还有一个是要求能够复制底层类型.选择了第三种方案。
对 ValueType
可复制构造的要求非常好 - 因为不可复制构造的类型不可能存储在 std::any
实例中,std::any_cast
可能作为好吧,让一个总是失败的转换成为编译器错误。
现在,ValueType any_cast(any&& operand)
的实现不允许移动这一事实似乎是一种疏忽 - 毕竟,副本是移动的完美实现,并且实现可以自由委托如果移动构造函数存在,则作业到移动构造函数,如果不存在,则复制构造函数。
在撰写本文时,问题处于 WP 状态,which means:
WP - (Working Paper) - The proposed resolution has not been accepted as a Technical Corrigendum, but the full WG21/PL22.16 committee has voted to apply the Defect Report's Proposed Resolution to the working paper.
在此处查看 lwg 以获取更多信息:http://wg21.cmeerw.net/lwg/issue2509
提议的决议确实是
For the third form, if is_move_constructible_v<ValueType>
is true and is_lvalue_reference_v<ValueType>
is false, std::move(*any_cast<remove_reference_t<ValueType>>(&operand))
, otherwise, *any_cast<remove_reference_t<ValueType>>(&operand)
以及列出 WP 的缺陷报告列表:http://cplusplus.github.io/LWG/lwg-defects.html#2509
在根据可用规范 in this Wiki 实现 C++17 的 std::any
时,我偶然发现了一些对我来说似乎荒谬的东西:
std::any_cast
的 In the definition,用于从 std::any
实例中检索值,r-value[=38= 的重载] 提供参考文献(这是第三个):
template< class ValueType >
ValueType any_cast(any&& operand); // (3)
现在,概要下方列出了适用于重载 2 和 3 的要求(这意味着还包括右值重载):
2-3)
Returns*any_cast<std::remove_reference_t<ValueType>>(&operand)
定义似乎实际上不允许移动数据!
函数调用只是重定向到基于指针的重载;有关 operand
临时性质的信息丢失了!
是不是有意让我不能搬出any实例?这只是维基中的一个错误吗?我错了吗?
不需要复制的std::any
实现是完全可以做到的。只有一个问题:当用户请求 std::any
的副本时,你会怎么做?这个问题的一个解决方案是让 std::any
只移动,另一个是如果底层类型是只移动,让它在复制构造函数上抛出异常,还有一个是要求能够复制底层类型.选择了第三种方案。
对 ValueType
可复制构造的要求非常好 - 因为不可复制构造的类型不可能存储在 std::any
实例中,std::any_cast
可能作为好吧,让一个总是失败的转换成为编译器错误。
现在,ValueType any_cast(any&& operand)
的实现不允许移动这一事实似乎是一种疏忽 - 毕竟,副本是移动的完美实现,并且实现可以自由委托如果移动构造函数存在,则作业到移动构造函数,如果不存在,则复制构造函数。
在撰写本文时,问题处于 WP 状态,which means:
WP - (Working Paper) - The proposed resolution has not been accepted as a Technical Corrigendum, but the full WG21/PL22.16 committee has voted to apply the Defect Report's Proposed Resolution to the working paper.
在此处查看 lwg 以获取更多信息:http://wg21.cmeerw.net/lwg/issue2509
提议的决议确实是
For the third form, if
is_move_constructible_v<ValueType>
is true andis_lvalue_reference_v<ValueType>
is false,std::move(*any_cast<remove_reference_t<ValueType>>(&operand))
, otherwise,*any_cast<remove_reference_t<ValueType>>(&operand)
以及列出 WP 的缺陷报告列表:http://cplusplus.github.io/LWG/lwg-defects.html#2509