何时不能将对象转换为引用? [英] When can't an object be converted to a reference?

查看:120
本文介绍了何时不能将对象转换为引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从 http://code.google.com/p/enhsim 编译以下代码行:

I want to compile the following line of code from http://code.google.com/p/enhsim:

enh::eout << enh::setw(26);

gcc会出现以下错误:

gcc gives the following error:

error: no match for 'operator<<' in 'enh::eout << enh::setw(26)'

但是 EnhSimOutput class(其中 enh :: eout 是一个实例)声明:

But the EnhSimOutput class (of which enh::eout is an instance) does declare:

EnhSimOutput& operator<< (setw& p);

如果我实现一个按值接受对象的操作版本, p>

This problem goes away if I implement a version of the operation that accepts the object by value:

EnhSimOutput& operator<< (setw p);

或如果我创建 enh :: setw object as a local,ie:

or if I create the enh::setw object as a local, i.e.:

enh::setw wValue(26);
enh::eout << wValue;

我的问题是:gcc为什么不选择操作符的开头是?

My question is this: why does gcc not select the "by-reference" version of the operator to begin with?

编写这段代码的开发人员清楚地使它编译,但默认gcc拒绝这样做。为什么单独声明为局部变量和局部变量之间有区别?

The developers who wrote this code clearly made it compile, yet default gcc refuses to do it. Why is there a difference between an object declared separately as a local variable and a local created inline?

推荐答案

enh :: setw(26); 右值。实际上,这样的临时性是右值。 Rvalues有特殊的属性。其中一个是他们的地址不能被采取(& enh :: setw(26); 是非法的),他们通常不能绑定到引用非const(一些临时可以绑定到对非const的引用,但是它们经历特殊的规则:通过引用非const来调用临时对象和捕获异常对象的成员函数在后一种情况下,临时偶数是左值)。

The value enh::setw(26); is an rvalue . Actually, temporaries like that are rvalues. Rvalues have special properties. One of them is that their address can't be taken (&enh::setw(26); is illegal), and they can't generally bind to references to non-const (some temporaries can bind to references to non-const, but these undergo special rules: Calling member functions on temporary objects and catching exception objects by reference to non-const. In the latter case, the temporary even is an lvalue).

有两种表达式: lvalues 表示对象(反过来可能存储一个值)或函数, ,用于表示从对象读取或由临时表,数字字面量和枚举常量表示的值。在C ++ 03中,为了能够将这样的值传递给接受其值的引用的函数,有一个规则,它们可以被引用到const接受: setw const& p 会接受它。也就是说,你必须像这样声明你的操作符:

There are two kind of expressions: lvalues that denote objects (that in turn may store an value) or functions, and rvalues which are meant to represent values read out of an object or represented by temporaries, numeral literals and enumerator constants. In C++03, to be able to pass such values to a function that accepts its value by-reference, there is a rule that they can be accepted by reference-to-const: setw const& p would accept it. That is, you would have to declare your operator like this:

EnhSimOutput& operator<< (setw const& p);

这有点不幸,因为你不能消除常量左值 const enh :: setwe(26); 例如)和非const或const值(如 enh :: setw(26) / code>这是一个非常量临时)。此外,如果你去,那个参数不能调用非const成员函数,因为它是一个引用到const。因此,下一个C ++版本C ++ 1x引入了一种新的引用,即所谓的 rvalue-references ,它修复了这一点。

That's a bit unfortunate, because you can't disambiguate constant lvalues (objects you created on the stack using const enh::setw e(26); for example) and non-const or const rvalues (like enh::setw(26); which is a non-const temporary). Also, if you go by that, the parameter can't have called non-const member functions on it, because it's a reference-to-const. For that reason, C++1x, the next C++ version, introduce a new kind of reference, so-called rvalue-references which fixes that.


Microsoft Visual C ++ 编译器将rvalues绑定到非const的引用, (你必须至少使用警告级别4才能显示)。这是不幸的,因为问题出现时移植到其他编译器,在标准合规性更严格。

The Microsoft Visual C++ compiler binds rvalues to references to non-const, but gives out a warning when doing that (you have to use at least warning level 4 for it to show up). That's unfortunate, because problems rise up when porting to other compilers that are more strict in Standard compliance.

这篇关于何时不能将对象转换为引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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