English 中文(简体)
对象何时不能被转换为引用?
原标题:
  • 时间:2009-01-15 03:41:31
  •  标签:

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

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

GCC 给出以下错误:

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

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

EnhSimOutput& operator<< (setw& p);

如果我实现一个接受对象值的版本,这个问题就会解决:

EnhSimOutput& operator<< (setw p);

如果我将enh::setw对象创建为局部的,即:

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

我的问题是:为什么GCC首选不是“按引用”版本的运算符?

编写这些代码的开发人员明显做到了编译,但默认的gcc拒绝这样做。为什么在单独声明为局部变量和内联创建的局部变量之间会有差异?

最佳回答

该值 enh::setw(26); 是一个rvalue。实际上,像这样的临时变量都是 rvalue。Rvalue 具有特殊的属性之一就是它们的地址无法被取得(&enh::setw(26); 是不合法的),它们通常无法绑定到非 const 引用(某些临时变量可以绑定到非 const 引用,但这些遵循特殊规则:调用临时对象的成员函数并通过引用非 const 捕获异常对象。在后一种情况下,临时变量甚至是一个lvalue)。

有两种表达式:左值(lvalues)表示对象(反过来也可能存储值)或函数,右值(rvalues)旨在表示从对象中读取或由临时变量,数字文字和枚举常量表示的值。在 C++03 中,要能够将这些值传递给按引用传递其值的函数,存在一条规则,即它们可以接受对 const 的引用:setw const& p 将接受它。也就是说,您必须像以下这样声明您的运算符:

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

这有点不幸,因为您无法消除常量lvalue(例如,使用const enh :: setw e(26)在堆栈上创建的对象)和非常量或常量rvalue(例如enh :: setw(26),它是临时的非常量)之间的歧义。此外,如果按照此方式进行,参数不能在其上调用非常量成员函数,因为它是对常量的引用。出于这个原因,C ++1x,即下一个C ++版本,引入了一种新的引用,即所谓的 rvalue-references ,可以解决此问题。


Microsoft Visual C++ 编译器将 rvalues 绑定到非 const 引用,但在执行此操作时发出警告(您必须至少使用警告级别 4 才能看到)。这是不幸的,因为在移植到其他符合标准的编译器时会出现问题。

问题回答

我的猜测是,EnhSimOutput& operator<< (setw& p); 通过非const引用传递,但值26在不能被修改的意义上是“const”的。尝试将其设置为 EnhSimOutput& operator<< (const setw& p);

或者尝试

int nNumber = 26;  
enh::eout << enh::setw(nNumber);




相关问题
热门标签