正在施放带有“ Int”类型的临时性
Is casting a temporary with type `int` to a reference safe?
在以下程序中:
int Func()
{
int a = { 10 };
return a;
}
int main()
{
int& r = (int&)(const int&)Func();
r = 5;
}
r
是对int
类型的临时性的引用。但是,除非将临时工正常分配给参考,否则临时工会立即被销毁。上面的任务似乎并不正常。在标准C ?
r
安全是否安全简介: C风格的铸件等效于(C 17 [Expr.cast]):
int& r = const_cast<int&>( static_cast<const int&>(Func()) );
在子表达static_cast<const int&>(Func())
中,行为由C 17 [Expr.static.cast]/4(其中T
是被施放的类型):
如果
的结果T
是参考类型,则效果与执行 某些发明的临时变量t
(11.6)的声明和初始化T t(e);
,然后使用临时变量作为转换
在这种情况下,T
是const int&
,因此参考的初始化类似于const int& t(Func());
。
现在,此代码中有两个问题:
- 临时类型
- 涉及的临时寿命
临时类型是const int
(C 17 [DCL.Init.ref]/5.2.1.2)。因此,您的代码通过修改常量对象会导致不确定的行为。链接到其他有关此主题的问题
在此答案的其余部分(解决生命周期问题)中,我假设您将r = 5
更改为仅读取r
的语句。
随着CWG 1299的应用,参考链的行为发生了变化。缺陷于2011年4月提交,并于2017年3月解决。该分辨率未出现在C 17(N4659)中;它仅在C 17个草稿中出现。
该分辨率具有状态DRWP,我对此的理解是,它意味着它追溯适用于C 17,但不适用于C 14(如果某人想确认或纠正这将很棒)。
无论如何,在某些情况下,该决议可以超越参考链。措辞为(n4762 class.temporary/6):
[...]引用绑定到的临时对象,或临时对象,该对象是 glvalue of to to to the the Lifetime bond bodive of to to to to to to bobignt的临时对象。该参考已绑定获得 通过以下一个:
- [...]
- a
const_cast
,static_cast
,dynamic_cast
或reinterpret_cast
转换,没有用户定义的转换,这是glvalue操作数,这是指glvalue的一种表达式,它是指操作系统指定的对象,或者涉及其完整对象或完整对象或一个对象
在CWG1299之前,本段仅应用于初始化prvalue的引用,但是现在它可以应用于指定对象是临时对象的任何表达式类别初始化参考的情况。
。请注意,在C 17中的暂时性化的作品是,当物质化发生时,prvalue被转换为xvalue,而该xvalue是上面的粗文本所指的glvalue。
现在甚至包含一个示例来确认这一点:
const int& b = static_cast<const int&>(0);
//临时int的寿命与b
另一个已删除答案中显示的编译器的行为必须应用于CWG1299的分辨率。
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 模板元程序查找相似的连续类型名称
- 是否可以从int转换为enum类类型
- 构造函数正在调用一个使用当前类类型的函数
- 我应该使用什么来代替void作为变体中的替代类型之一
- 正在施放带有“ Int”类型的临时性