我可以在对 std::visit 的调用中更改 std::variant 中的保留类型吗
May I change the held type in a std::variant from within a call to std::visit
以下代码是否调用了未定义的行为?
std::variant<A,B> v = ...;
std::visit([&v](auto& e){
if constexpr (std::is_same_v<std::remove_reference_t<decltype(e)>,A>)
e.some_modifying_operation_on_A();
else {
int i = e.some_accessor_of_B();
v = some_function_returning_A(i);
}
}, v);
特别是,当变体不包含 A
时,
此代码重新分配 A
,同时仍然持有对先前持有的 B
类型对象的引用。
但是,由于在分配后不再使用引用,
我觉得代码没问题。
但是,标准库是否可以免费实施 std::visit
以上是未定义的行为?
代码没问题。
std::visit
的规范中没有要求访问者不更改调用它的任何变体的备选方案。唯一的要求是:
Requires: For each valid pack m
, e(m)
shall be a valid expression. All such expressions shall be of the same type and value category; otherwise, the program is ill-formed.
您的访问者是每个 m
的有效表达式,并且总是 returns void
,因此它满足要求并具有明确定义的行为。
以下代码是否调用了未定义的行为?
std::variant<A,B> v = ...;
std::visit([&v](auto& e){
if constexpr (std::is_same_v<std::remove_reference_t<decltype(e)>,A>)
e.some_modifying_operation_on_A();
else {
int i = e.some_accessor_of_B();
v = some_function_returning_A(i);
}
}, v);
特别是,当变体不包含 A
时,
此代码重新分配 A
,同时仍然持有对先前持有的 B
类型对象的引用。
但是,由于在分配后不再使用引用,
我觉得代码没问题。
但是,标准库是否可以免费实施 std::visit
以上是未定义的行为?
代码没问题。
std::visit
的规范中没有要求访问者不更改调用它的任何变体的备选方案。唯一的要求是:
Requires: For each valid pack
m
,e(m)
shall be a valid expression. All such expressions shall be of the same type and value category; otherwise, the program is ill-formed.
您的访问者是每个 m
的有效表达式,并且总是 returns void
,因此它满足要求并具有明确定义的行为。