std::variant
提供以下访问功能:
std::get_if
:将pointer返回到替代方案。 variant
如果不是无效的指针,而是返回一个指针,以返回存储在thy the the the的变体中的值。否则,返回零指针值。
template <std::size_t I, typename... Ts> auto* std::get_if(std::variant<Ts...>* pv) noexcept;
的实现大致看起来像这样:
pv
pv->index() == I
:将Reference到
pv
在无效的访问中。
template <std::size_t I, typename... Ts>
auto* std::get_if(std::variant<Ts...>* pv) noexcept
{
if(pv == nullptr) return nullptr;
if(pv->index() != I) return nullptr;
return &(pv->real_get<I>());
}
IF
std::get
,返回对存储在variant
中的值的引用。否则,扔
throw
.
这意味着
template <std::size_t I, typename... Ts>
auto& std::get(std::variant<Ts...>& v);
v.index() == I
我想要一个不安全的访问功能:
IS
v
std::bad_variant_access
是否有未定义的行为
get
实例在代码路径中包含特定类型。另外,在编写已经单独检查
template <std::size_t I, typename... Ts>
auto& std::get(std::variant<Ts...>& v)
{
if(v.index() != I) throw std::bad_variant_access{};
return v.real_get<I>();
}
noexcept
variant
)的通用代码时,这将很有用。 示例实现:
pv == nullptr
标准中有类似的东西吗?我找不到它。如果没有,则可以为
v.index() != I
实施,还是我需要推出自己的variant
@ @T.C指出。在评论中,您的第一个和第三个Desiderata是相互不相容的。这是在N3279
基本上有两类合同:狭窄而宽。范围内的功能或操作合同未指定任何未定义的行为。 这样的合同没有前提条件。在标准库中仅标记具有广泛合同的功能。
otoh,一份narrow合同是一份不广泛的合同。当以违反已记录的合同的方式调用时,功能或操作的狭窄合同会导致未定义的行为
。它们不能被标记
v.index() != I
。取而代之的是,您可以期望的最好的是记录它们为“投掷:没有”。
似乎您很幸运,目前的visit
我认为您必须自己实施整个变体。 尽管不受限制的工会可能会有所帮助 - 他们至少解决了在同一位置将多种类型放置在同一位置的情况下。
no.
C ++标准确实可以保证变体代表一个联合,其数据必须在结构本身中保存:...变体对象包含的值,分配在变体对象的存储中。实现不允许使用其他存储(例如动态内存)分配包含的值。