`std::any_cast` 返回一个副本

Posted

技术标签:

【中文标题】`std::any_cast` 返回一个副本【英文标题】:`std::any_cast` returns a copy 【发布时间】:2017-01-28 02:50:49 【问题描述】:

我正在阅读documentation for std::any_cast,我发现 API 的强制转换要么返回一个值到持有的对象,要么返回一个指向它的指针,这很奇怪。为什么不返回参考?每次使用非指针类型参数调用函数时都需要进行复制。

我可以看到转换的指针版本可能会更多地表明意图并且可能更清楚一些,但是为什么不将返回的值作为这样的引用呢?

template<typename ValueType>
ValueType& any_cast(any* operand);

而不是

template <typename ValueType>
ValueType* any_cast(any* operand);

此外,即使您要求引用,强制转换也会删除引用并将副本返回到存储的对象,请参阅此处http://en.cppreference.com/w/cpp/utility/any/any_cast 函数重载 1-3 的返回值的解释@

【问题讨论】:

如果输入指针是nullptr呢?不能取消引用以满足返回的引用。我认为您真正要问的是为什么将引用作为输入的any_cast 的重载返回副本而不是引用作为输出,不是吗? any_cast 提供参考,如果你告诉它。这就像说static_cast 总是返回一个副本。 不能被引用的给定类型的有效指针值的数量取决于人们对标准的阅读和标准的演变,但它肯定大于 0,因为它包含空指针。 仔细想想,这似乎很奇怪。我猜您或某人™ 将不得不查找原始论文或论文,以找到理由。似乎不太实用,有异常问题和性能。 @Curious: any_cast&lt;Something&amp;&gt; 将在内部处理对象时删除引用,但它仍会返回 Something&amp; 作为输出。 【参考方案1】:

您可以在此处查看有关 C++ 标准的讨论:https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/ngSIHzM6kDQ

请注意,Boost 十多年来一直以这种方式定义 any_cast,而且它还匹配 static_cast 和朋友。因此,如果您需要参考,请执行以下操作:

any_cast<Foo&>(x)

与您在 C++ 中为旧的 _casts 所做的相同。

【讨论】:

是的,但这并不是真正的演员表。这里的“演员”一词用词不当。它是一种访问所包含对象的设备。 但是如果你看一下这里的文档en.cppreference.com/w/cpp/utility/any/any_cast,引用被删除了,对吧? @Curious:内部是的,但不在输出中,因为std::remove_reference_t 未应用于返回类型。返回类型是您在模板参数中要求的任何内容。 总结一下,使用此函数访问对象,您必须明确选择加入才能获得引用,否则,默认情况下,您可能会效率低下和异常问题。通过合理的设计,您将明确复制一份以获得一份副本。因此,虽然这个答案说明了情况的事实,但它没有回答“为什么没有返回的值是这样的引用”的问题。我看不出任何合理的理由。与演员表的相似性是一个美学问题,我绝对不同意那种愚蠢的一致性美的概念。

以上是关于`std::any_cast` 返回一个副本的主要内容,如果未能解决你的问题,请参考以下文章

使用带有decltype的std :: any_cast…为什么这段代码会抛出错误的any_cast?

Swift 计算属性返回底层数组的副本

如何返回向量的“只读”副本

java返回字符串副本啥意思

返回不包括指定键的字典副本

何时获取 numpy 数组的子矩阵返回视图但不返回副本?