请考虑以下代码段:
struct foo { };
template <typename F>
struct impl : F
{
impl(F&& f) : F{std::move(f)} { }
auto get() { return (*this)(); }
};
template <typename X>
auto returner(X&& x)
{
return impl{[&x]{ return x; }};
// ^~
}
int main()
{
auto x = returner(foo{}).get();
}
是否保证foo{}
在returner(foo{}).get()
表达式的整个持续时间内都有效?
或foo{}
仅为returner(foo{})
生存,因此在调用impl::get()
时会导致未定义的行为?
标准在[class.temporary]中说:
中临时对象在评估完整表达式的最后一步时被销毁(
)包含创建它们的点。
完整表达是
未评估的操作数,
一个常量表达式,
init-declarator或mem-initializer,包括初始化程序的组成表达式,
调用在临时对象([class.temporary])以外的对象的生命周期结束时生成的析构函数,或
一个表达式,它不是另一个表达式的子表达式 这不是一个完整表达的一部分。
我不确定与foo{}
相关的完整表达是returner(foo{})
还是returner(foo{}).get()
。
答案 0 :(得分:10)
这里重要的部分是:
完整表达式是一个表达式,它不是另一个表达式的子表达式,而不是完整表达式的一部分。< / p>
因此,在returner(foo{}).get()
中,returner(foo{})
是表达式returner(foo{}).get()
的子表达式,因此它不是完整表达式。因此:
是否保证在
foo{}
表达的整个过程中returner(foo{}).get()
都会存活?
是