gro*_*man 18 c++ const reference language-lawyer c++11
据已知特征的C++,一个常量引用延伸从函数返回的临时对象的生命时间,但是它可以接受使用恒定的参考到临时对象的成员从函数返回?
例:
#include <string>
std::pair<std::string, int> getPair(int n)
{
return {std::to_string(n), n};
}
int main(int, char*[])
{
const int x = 123456;
const auto& str = getPair(x).first;
printf("%d = %s\n", x, str.c_str());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
123456 = 123456
Run Code Online (Sandbox Code Playgroud)
Sme*_*eey 12
是的,这段代码完全可以接受.根据标准规则是([class.temporary]):
有两种情况,临时表演在不同于完整表达结束时被摧毁.第一个上下文是调用默认构造函数来初始化数组的元素.如果构造函数具有一个或多个默认参数,则在构造下一个数组元素(如果有)之前,对默认参数中创建的每个临时的销毁进行排序.
第二个上下文是引用绑定到临时的.引用绑定的临时对象或引用绑定到的子对象的完整对象的临时对象在引用 的生命周期内持续存在...
如您所见,突出显示的行清楚地表明对子对象的绑定引用是可接受的,因为完整对象也必须延长其生命周期.
请注意,first它确实有资格作为子对象[intro.object]:
- 对象可以包含其他对象,称为子对象.子对象可以是成员子对象(9.2),基类子对象(子句10)或数组元素.不是任何其他对象的子对象的对象称为完整对象.
它定义明确.
从标准:$ 12.2/6临时对象[class.temporary]:
(强调我的)
绑定引用的临时对象或绑定引用的子对象的完整对象的临时 对象在引用的生命周期内仍然存在
关于子对象,$ 1.8/2 C++对象模型[intro.object]:
(强调我的)
对象可以包含其他对象,称为子对象.子对象可以是成员子对象([class.mem]),基类子对象(Clause [class.derived])或数组元素.不是任何其他对象的子对象的对象称为完整对象.
first必须引用并且它是成员子对象std::pair,因此临时std::pair(即完整对象)的生命周期将延长,代码应该没问题.