Is it valid to bind non-const lvalue-references to rvalues in C++ 11?(modified)(在 C++ 11 中将非常量左值引用绑定到右值是否有效?(修改))
问题描述
我知道在 c++03 中,非常量引用不能绑定到右值.
I know in c++03, an an non-const reference cannot be bound to rvalues.
T&t = getT();
无效,在 C++11 中,我们可以这样做:T&&t = getT();
但是上面的代码怎么样,在 c++11 中能用吗?
T& t = getT();
is invalid, and in c++11, we can do this: T&& t = getT();
but what about the above code, should that work in c++11?
我用 vs11 测试了下面的代码:
I tested the codes below with vs11:
Foo getFoo() {
return Foo();
}
void fz(Foo& f) {
}
int getInt() {
return int();
}
void iz(int& i) {
}
int main() {
{
Foo& z = getFoo(); //ok
fz(getFoo()); //ok
int& z2 = getInt(); //error: initial value of reference to non-const must be an lvalue
iz(getInt()); //same as above
}
}
Foo
是自定义类,不明白为什么前两行编译.z
引用的临时对象在内部作用域的末尾销毁主要的.标准对此有任何说明吗?
Foo
is a custom class, I don't understand why the first two line compiles.The temporary referenced by z
is destructed at the end of the inner scope of main. Does the standard say anything about this?
class Foo {
public:
Foo() {
std::cout << "constructed
";
}
~Foo() {
std::cout << "destructed
";
}
};
我刚看到一个类似的问题:一个 VS2010 错误?允许在没有警告的情况下绑定非常量引用到右值?
I just saw a similar question: One VS2010 bug ? Allowing binding non-const reference to rvalue WITHOUT EVEN a warning?
推荐答案
这应该在 C++11 中工作吗?
should that work in c++11?
不,不应该.
Foo
是自定义类,不明白为什么前两行编译
Foo
is a custom class, I don't understand why the first two line compiles
它只能用 MSVC 编译.MSVC 有一个(可以说是有用的)编译器扩展,它允许将用户定义类型的左值绑定到右值,但标准本身禁止这样做.例如,请参阅这个现场示例,其中 GCC 4.7.2 拒绝编译您的代码.
It compiles only with MSVC. MSVC has an (arguably useful) compiler extension that allows binding lvalues of user-defined types to rvalues, but the Standard itself forbids this. See, for instance, this live example where GCC 4.7.2 refuses to compile your code.
标准对此有任何说明吗?
Does the standard say anything about this?
确实如此.根据 C++11 标准的第 8.5.3/5 段:
Indeed it does. Per paragraph 8.5.3/5 of the C++11 Standard:
对类型cv1 T1
"的引用由cv2 T2
"类型的表达式初始化,如下所示:
A reference to type "
cv1 T1
" is initialized by an expression of type "cv2 T2
" as follows:
——如果引用是左值引用和初始化表达式
— If the reference is an lvalue reference and the initializer expression
— 是左值(但不是位域),并且cv1 T1
"与cv2 T2
"引用兼容,或
— is an lvalue (but is not a bit-field), and "
cv1 T1
" is reference-compatible with "cv2 T2
," or
——有一个类类型(即T2
是一个类类型),其中T1
与T2
没有引用相关,并且可隐式转换为cv3 T3
"类型的左值,其中cv1 T1
"与cv3"引用兼容T3
" [...],
— has a class type (i.e., T2
is a class type), where T1
is not reference-related to T2
, and can be
implicitly converted to an lvalue of type "cv3 T3
," where "cv1 T1
" is reference-compatible with "cv3
T3
" [...],
然后引用绑定到第一种情况下的初始化表达式左值和左值结果在第二种情况下的转换(或者,在任何一种情况下,转换为适当的基类子对象物体).[...]
then the reference is bound to the initializer expression lvalue in the first case and to the lvalue result of the conversion in the second case (or, in either case, to the appropriate base class subobject of the object). [...]
[...]
——否则,引用应是对非易失性常量类型的左值引用(即,cv1 应为const),或者引用应该是一个右值引用.[ 示例:
double& rd2 = 2.0; // error: not an lvalue and reference not const
int i = 2;
double& rd3 = i; // error: type mismatch and reference not const
——结束示例 ]
这篇关于在 C++ 11 中将非常量左值引用绑定到右值是否有效?(修改)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在 C++ 11 中将非常量左值引用绑定到右值是否有效?(修改)
基础教程推荐
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- Windows Media Foundation 录制音频 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01