隐式转换:const参考与非const参考与非参考
-
11-10-2019 - |
题
考虑此代码,
struct A {};
struct B { B(const A&) {} };
void f(B)
{
cout << "f()"<<endl;
}
void g(A &a)
{
cout << "g()" <<endl;
f(a); //a is implicitly converted into B.
}
int main()
{
A a;
g(a);
}
这个 编译正常, ,运行良好。但是如果我改变 f(B)
至 f(B&)
, , 它 不编译. 。如果我写 f(const B&)
, ,再次 编译正常, ,运行良好。为什么原因和理由?
概括:
void f(B); //okay
void f(B&); //error
void f(const B&); //okay
对于每种情况,我想听听语言规范的原因,理由和参考。当然,功能签名本身不是不正确的。相当 A
隐式转换为 B
和 const B&
, ,但不喜欢 B&
, ,这会导致汇编误差。
解决方案
我想听听语言规范的原因,理由和参考
是 C ++的设计和演变 充足的?
不过,我允许非诉讼人通过非责任初始化[我评论:措辞不精确!]。例如:
void incr(int& rr) { ++rr; } void g() { double ss = 1; incr(ss); // note: double passed, int expected // (fixed: error in release 2.0) }
由于类型的差异
int&
不能指double
通过了,生成了一个临时的int
初始化ss
的价值。因此,incr()
修改了临时性, 结果没有反映回通话功能 [强调我的].
考虑一下:逐一引用的全部要点是,客户端传递了函数更改的内容,函数返回后, 客户必须能够观察更改.
其他提示
问题在于,从A到B对象的隐式转换产生了一个rvalue。非符合参考只能与lvalues结合。
如果B具有默认构造函数,则如果您更改 f(a)
拨电至 f(B())
.
--
LITB为什么是LVALUE提供了一个很好的答案: 堆栈溢出 - 经常使用的很少定义的术语:lvalue
--
用标准来解释这些函数调用如何失败或成功将过长。重要的是如何 B& b = a;
失败时 const B& b = a;
不会失败。
(来自N1905草案)
对“ CV1 T1”类型的引用是通过类型“ CV2 T2”的表达来初始化的:
- [是一个LVALUE,是参考兼容或隐式转换为参考兼容类型的LVALUE ...]
- 否则,引用应为非挥发性const类型(即CV1为const)。
这是 某些东西可转换为参考兼容类型的LVALUE。