假设我有一个功能
void set_value(MyType& x);
我希望用类型
的变量来调用它std::experimental::optional<MyType> myvar
我不能简单地致电set_value(*myvar)
,因为myvar
可能没有值。在所有情况下,如何安全地确保set_value()
myvar
的结果?
我想避免写作:
decltype(my_var)::value_type tmp;
set_value(tmp);
my_var = tmp;
答案 0 :(得分:3)
你可以这样做:
if (!my_var) { my_var.emplace(); }
set_value(*my_var);
但更好的方法是只需将set_value
的签名更改为:
MyType set_value();
所以你可以写完:
my_var = set_value();
输入/输出参数很糟糕。
答案 1 :(得分:2)
template<class F, class T>
decltype(auto) set_optional( F&& f, std::experimental::optional<T>& o ) {
if (!o) o.emplace();
return std::forward<F>(f)(*o);
}
现在你可以:
set_optional( set_value, myvar );
它有效。
但请注意,引用MyType
的函数需要输入和输出参数。仅返回输出参数。许多人将其重用于仅输出参数。这会导致类似上面遇到的问题以及不必要的默认构造。
set_value(*myvar);
您可以内联执行此操作:
if (!myvar) myvar.emplace();
set_value(*myvar);
如果我们构造它,如果为空,则使用它。
或者,不同的重构(我觉得很好):
template<class T, class...Args>
T& emplace_or( std::experimental::optional<T>& o, Args&&...args ) {
if (!o) o.emplace(std::forward<Args>(args)...);
return *o;
}
然后:
set_value(emplace_or(myvar));
或者最后一个选项:
set_value(void(!myvar?myvar.emplace(),void(),3:16),*myvar)
void(),3:16
:对于可选的如此喜爱的“你好世界”,他们给了它们唯一的内容,任何相信它都参与其中的内容不应该是段错误的,而是要有正确的程序。