在C ++ 11中绑定非const常量引用到右值是有效的吗?(修改) [英] Is it valid to bind non-const lvalue-references to rvalues in C++ 11?(modified)

查看:173
本文介绍了在C ++ 11中绑定非const常量引用到右值是有效的吗?(修改)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在c ++ 03中,一个非const引用不能绑定到右值。



t = getT(); 无效,在c ++ 11中,我们可以这样做: T& t = getT(); 但是上面的代码,应该在c ++ 11中工作吗?



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(); //错误:引用非初始值必须是一个左值
iz(getInt()); //与上面相同
}
}

Foo 是一个自定义类,我不明白为什么前两行编译。被 z 引用的临时被破坏内部范围主。标准是否对此有所说明?

  class Foo {
public:
Foo b $ b std :: cout<< constructed \\\
;
}
〜Foo(){
std :: cout< destructed\\\
;
}
};

我刚刚看到一个类似的问题:一个VS2010错误?允许绑定非const引用到右值WITHOUT EVEN警告?

解决方案


在c ++ 11中工作?


不,它不应该。


Foo 是一个自定义类,我不明白为什么前两个line compiles


它只能与MSVC一起编译。 MSVC有一个(可以说是有用的)编译器扩展,允许将用户定义类型的左值绑定到右值,但是标准本身禁止。例如,请参阅此实例,其中GCC 4.7.2拒绝编译您的代码。

$ b


。按照C ++ 11标准的第8.5.3 / 5节:


引用类型 cv1 T1 由类型为 cv2 T2 的表达式初始化,如下所示:



- 如果引用是一个左值引用,并且初始化器表达式


是一个左值(但不是位字段) cv1 T1 cv2 T2

$ b

- 具有类类型(即 T2 是类类型),其中 T1 引用相关 T2 ,并且可以
隐式转换为类型为 cv3 T3 [...],其中 cv1 T1 引用兼容 cv3
T3


,那么引用将绑定到初始化器表达式lvalue在第一种情况下和左值结果
的转换在第二种情况下(或者,无论如何,到对应的
的适当的基类子对象)。 [...]



[...]



- 对非易失性const类型的左值引用(即cv1应为
const),或引用应为右值引用
。 [例如:

  double& rd2 = 2.0; // error:not a lvalue and reference not const 
int i = 2;
double& rd3 = i; // error:type mismatch and reference not const



I know in c++03, an an non-const reference cannot be bound to rvalues.

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?

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 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\n";
  }
  ~Foo() {
    std::cout << "destructed\n";
  }
};

I just saw a similar question: One VS2010 bug ? Allowing binding non-const reference to rvalue WITHOUT EVEN a warning?

解决方案

should that work in c++11?

No, it should not.

Foo is a custom class, I don't understand why the first two line compiles

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?

Indeed it does. Per paragraph 8.5.3/5 of the C++11 Standard:

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

— is an lvalue (but is not a bit-field), and "cv1 T1" is reference-compatible with "cv2 T2," or

— 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). [...]

[ ...]

Otherwise, the reference shall be an lvalue reference to a non-volatile const type (i.e., cv1 shall be const), or the reference shall be an rvalue reference. [ Example:

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

—end example ]

这篇关于在C ++ 11中绑定非const常量引用到右值是有效的吗?(修改)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆