std::get_if (std::variant) 通过指针而不是值/&/const& 获取变体参数是不是有任何实际原因?

Posted

技术标签:

【中文标题】std::get_if (std::variant) 通过指针而不是值/&/const& 获取变体参数是不是有任何实际原因?【英文标题】:Is there any practical reason why std::get_if (std::variant) takes a variant argument by pointer instead of by value/&/const&?std::get_if (std::variant) 通过指针而不是值/&/const& 获取变体参数是否有任何实际原因? 【发布时间】:2021-11-15 03:15:46 【问题描述】:

我从未使用过std::get_if,并且由于它的名称与std::get 不同,我看不出它的参数应该是指针¹ 的原因(而std::get 有一个引用参数)。


¹如果它也被命名为 std::get,那么重载决议就足够了。


是的,我的问题可能被Is it absolutely necessary for std::any_cast() and std::get_if(std::variant) to take pointer as an argument?的问题所欺骗,但关键是那里没有答案地址@ 987654329@ vs std::get,只有一条评论;唯一的答案集中在std::any_cast

【问题讨论】:

我似乎记得 Jason Turner 在 C++ Weekly 视频之一中谈到了为什么。 这能回答你的问题吗? Is it absolutely necessary for std::any_cast() and std::get_if(std::variant) to take pointer as an argument? @xskxzr,不,因为我在问题中添加了原因。 【参考方案1】:

这是因为get_ifnoexcept,所以永远不会抛出异常。为了实现这一点,它必须返回一个pointer,以便在访问失败时可以返回nullptr

因为它返回了指针,所以它必须取variant的指针。如果它接受variant的引用,那么它必须能够接受variant&const variant&variant&&const variant&&的类型,但是指针保持引用限定是没有意义的.

考虑到get_if 接受variant&&,你所做的就是返回一个xvalue 的地址,这很糟糕。即使get_if 只允许variant&const variant&,后者仍然可以接受variant&& 并返回一个悬空。

【讨论】:

第二段的解释我实在看不懂。 @Enlico。假设get_if接受引用,那么接受variant&&时应该返回什么类型? variant&& 只会绑定到右值,对吧?那么返回nullptr 不是正确的选择吗? @Enlico。这可以是一个选择,但这也意味着get_if(std::move(v)) 将返回一个nullptr,即使返回其地址没有问题。 就像unique_ptr.get() 我看不出它对variant 无效的原因。【参考方案2】:

据我所知,它基于动态转换逻辑。可能失败的动态转换需要一个指针并返回一个指针。

同样,get that can fail需要一个指针并返回一个。

但实际上,这看起来像是一个无关紧要的小决定。

【讨论】:

以上是关于std::get_if (std::variant) 通过指针而不是值/&/const& 获取变体参数是不是有任何实际原因?的主要内容,如果未能解决你的问题,请参考以下文章

具有 std::map 和 std::variant 的不完整类型

如何将 std::variant 作为 VARIANT* 传递给 ExecWB?

使用 std::variant 的静态多态性

std::visit 无法推断 std::variant 的类型

将 std::unique_ptr 的子类与 std::variant 一起使用

我可以将 std::variant<Ts...> 分配给/从 std::variant<Ts..., Ys...> 分配/构造吗?