假设我们有一个返回std :: optional< A>的函数.那么在基于范围的for循环中使用结果的正确方法是什么?最简单的方法不起作用:
for (auto&& e : a().value()) {
// ^--- A&& is returned, so A is destructed
// before loop starts
如果我们有T optional :: value()&& ;;这个问题就不存在了.而不是T&& optional :: value()&&,但STL和Boost都以第二种方式定义它.
处理这种情况的正确方法是什么?我不喜欢我能想到的两种解决方案(sandbox):
std::experimental::optional<A> a() {
// ...
}
void ok1() {
// ugly if type of A is huge
for (auto&& e : A(a().value())) {
// ...
}
}
void ok2() {
// extra variable is not used
// if for some reason we are sure that we have a value
// and we skip checks
auto&& b = a();
for (auto&& e : b.value()) {
// ...
}
}
// it may be that the best choice is to define
A aForced() {
return A(a().value());
}
最佳答案 这解决了您的问题:
template<class T>
std::decay_t<T> copy_of(T&& t){
return std::forward<T>(t);
}
template<class T, std::size_t N>
void copy_of(T(&)[N])=delete;
然后:
for(auto&& x:copy_of(a().value()))
copy_of技术通常解决返回用于for(循环)的rvalue引用的函数.
另一种方法是写入value_or_run(T&&,F& f),它取一个lambda也很有用.在F中你可以做你想做的任何事情,比如扔,它会返回T而不是T&& ;.
同样,value_or.
我个人的可选使用emplace语法为value_or – 如果你正在使用的那个有,那么.value_or(throw_if_empty {}),其中throw_if_empty有一个运算符T()抛出可选的空错误.