与此问题相关:Return value or rvalue reference? - 我发现以下示例似乎不安全,至少使用g ++ 6.1.0和Boost 1.60.0。
#include <boost/optional.hpp>
struct A {
A();
A(const A&);
A(A&&);
~A();
int* begin();
int* end();
int* buf;
};
boost::optional<A> f();
int test() {
int res = 0;
for (int n : f().value())
res += n;
return res;
}
当我查看生成的汇编代码时,我肯定会在A::~A()
,A::begin()
等之前看到A::end()
被调用。
问题是:在f()
返回的临时工作消失之前强行移动建筑的最不具侵扰性的方法是什么?
答案 0 :(得分:0)
我写了一个简单的模板函数,在一个右值上调用一个移动构造函数,但在左值上只返回相同的东西。
template <typename T>
T extend_if_rval(T&& x) {
return std::forward<T>(x);
}
然后,如果我将for
更改为:
for (int n : extend_if_rval(f().value()))
生成的程序集看起来很好:它首先在A::A(A&&)
,A::begin()
之前调用A::end()
,并在循环结束后最终调用A::~A()
。 (当然它仍然可以抛出一个异常,但这是通过示例的设计。)
答案 1 :(得分:0)
创建一个显式的临时文件:
for (int n : A(f().value())) { /* ... */ }