C++ 隐式转换:常量引用vs非常量引用vs非引用
考虑一下这个代码C++ 隐式转换:常量引用vs非常量引用vs非引用,c++,reference,implicit-conversion,const-reference,C++,Reference,Implicit Conversion,Const Reference,考虑一下这个代码 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); } 我想从
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);
}
我想从语言规范中了解每种情况的原因、基本原理和参考。当然,函数签名本身并不是不正确的。相反,
A
隐式转换为B
和常量B&
,而不是转换为B&
,这会导致编译错误。问题是,从A到B对象的隐式转换会产生一个右值。非常量引用只能绑定到左值
如果B有一个默认构造函数,那么如果将f(a)
调用更改为f(B())
,则会得到相同的行为
--
litb为什么是左值提供了一个很好的答案:
--
参考标准解释这些函数调用是如何失败或成功的将是过长的。重要的是如何B&B=a代码>在常数B&B=a时失败代码>不会失败
(摘自草案n1905)
对“cv1 T1”类型的引用由“cv2 T2”类型的表达式初始化,如下所示:
-[是左值,并且与引用兼容或可隐式转换为与引用兼容类型的左值…]
-否则,参考应为非易失性常数类型(即cv1应为常数)
某事物可转换为引用兼容类型的左值的情况
我想从语言规范中了解原因、基本原理和参考
是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
,因此生成了一个临时文件来保存由ss
初始化的int
。因此,incr()
想想看:通过引用调用的整个要点是客户端传递函数更改的内容,在函数返回后,客户端必须能够观察到更改为什么@Nawaz的问题有23分钟没有得到回答,当我回答时,你比我早30秒给出了答案。真是神奇!哈哈,+1。@Chris:请同时引用相关参考文献,这样我就可以自己探索相关概念。严格来说,你根本不能创建左值或右值,因为值类别是表达式(编译时)的属性,而不是对象(运行时)。@Fred,true。将“转换…创建一个右值”更改为“转换…生成一个右值”,这是我所拥有的标准草案中的术语。答案很好,看到更多解释的引用令人鼓舞。有趣的是:在ARM中,主要表达式的左值的确定如下:“如果标识符为,则结果为左值。”…“如果成员为,则结果为左值。”。我想知道这到底意味着什么,因为它也定义了“左值是指对象或函数的表达式。”。嗯,可能它只是指“如果它指对象或函数,则结果为左值。”。“这很好。我认为它更好地回答了我的问题,因为它解释了为什么它不被允许。我接受这个作为我问题的答案。:-)
void incr(int& rr) { ++rr; }
void g()
{
double ss = 1;
incr(ss); // note: double passed, int expected
// (fixed: error in release 2.0)
}