这是受CPPReference
的示例启发的示例struct S {
operator int() { throw 42; }
};
int main(){
variant<float, int> v{12.f}; // OK
cout << std::boolalpha << v.valueless_by_exception() << "n";
try{
v.emplace<1>(S()); // v may be valueless
}
catch(...){
}
cout << std::boolalpha << v.valueless_by_exception() << "n";
}
对于一个编译器,我尝试了IT输出
false,true
意味着emplace
导致变体变得无价值
我不明白的是如何发生。特别是我不明白为什么要调用 emplace
,我希望该程序什至不称呼它,因为从s转换为int grom thr。
请注意相关std::variant::emplace
超载的签名:
template <size_t I, class... Args>
std::variant_alternative_t<I, variant>& emplace(Args&&... args);
需要一包转发参考。这意味着在评估函数参数时,未调用从S
到int
的转换操作员;它被称为emplace
的主体内部。由于试图将int
构造到位将失败,因此这种变体的例外是毫无价值的。
也许可以实现variant
,以便对于易于移动的类型,在尝试构造之前保存旧值对标准给出的类型实现的限制。