临时对象最初是常量吗
Is temporary object originally const?
这是UB代码吗?
struct A
{
void nonconst() {}
};
const A& a = A{};
const_cast<A&>(a).nonconst();
换句话说,(临时)对象最初是const
吗?我看过标准,但找不到答案,所以希望能引用相关章节。
编辑:对于那些说A{}
不是const
的人,你能做A{}.nonconst()
吗?
参考a
的初始化由[dcl.init.ref]/5(bold mine):给出
否则,如果初始值设定项表达式
- 是一个右值(但不是位字段)[…]
则第一种情况下初始值设定项表达式的值和第二种情况下转换的结果称为转换后的初始值设定值。如果转换后的初始值设定项是prvalue,则其类型T4将调整为类型"cv1T4"([conv.qual]),并应用临时物化转换([conw.rval])。
因此,这意味着初始化引用的类型prvalue表达式A{}
被调整为const A
。
然后[conv.rval]状态:
T类型的prvalue可以转换为T类型的xvalue。此转换初始化T类型的临时对象([class.temporary])。
因此,绑定到引用的临时对象的类型与调整后的prvalue
类型相同:const A
。
因此,代码const_cast<A&>(a).nonconst();
是未定义的行为。
临时的类型是用什么类型声明它。
不幸的是,正如Oliv在他们的答案中指出的那样,引用初始化规则将类型转换为与引用类型匹配,因此在这种情况下,a
实际上指的是const A
。它基本上是在做
using const_A = const A;
const A& a = const_A{};
因为如果你想阻止过载集接受常量prvalue,你实际上可以创建常量prvalues,所以你需要有
ret_type function_name(some_type const&&) = delete;
否则,如果你有
ret_type function_name(some_type const&)
在重载设置中,如果您只删除,则常量prvalue将绑定到该值
ret_type function_name(some_type&&)
相反。你可以在中看到这一点
struct bar{};
void foo(bar const&) { std::cout << "void foo(bar const&)n"; }
void foo(bar&&) =delete;
using c_bar = const bar;
int main()
{
foo(c_bar{});
}
这里,调用void foo(bar const&)
是因为c_bar{}
实际上是const
,而不是在使用foo(bar{});
时得到已删除的函数错误。添加
void foo(bar const&&) = delete;
需要实际停止CCD_ 17的编译。
- 为什么当我们有常量引用时创建临时对象?
- C++:允许临时对象调用非常量成员函数的设计理念是什么?
- 常量引用函数参数:是否可以禁止临时对象?
- 为什么临时对象可以绑定到常量引用?
- 为什么常量引用不能延长通过函数传递的临时对象的生存期?
- C++:如何创建一个临时对象,包含一个指针 - 常量或非常量,具体取决于上下文
- 使用常量引用延长临时对象的寿命
- 关于将临时对象传递给常量引用
- 将临时对象绑定到常量引用
- 临时对象最初是常量吗
- 为什么不对临时对象进行非常量引用
- 堆上是否会分配内存以支持临时对象到常量引用的嵌套绑定
- 传递给存储常量引用的成员的临时对象的生存期
- 正在返回临时对象并绑定到常量引用
- 为什么我们可以非常量引用临时对象并延长其生命周期
- 为什么非常量引用参数可以绑定到临时对象
- 返回常量引用与临时对象
- C++悬空的常量引用临时对象
- 对常量临时对象的引用出现意外行为
- 如果没有对临时对象的常量引用,它会被删除吗