考虑此代码,

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 隐式转换为 Bconst 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

GOTW#88:“最重要的const”的候选人

堆栈溢出 - 非const引用如何无法绑定到临时对象?

--

用标准来解释这些函数调用如何失败或成功将过长。重要的是如何 B& b = a; 失败时 const B& b = a; 不会失败。

(来自N1905草案)

对“ CV1 T1”类型的引用是通过类型“ CV2 T2”的表达来初始化的:
- [是一个LVALUE,是参考兼容或隐式转换为参考兼容类型的LVALUE ...]
- 否则,引用应为非挥发性const类型(即CV1为const)。

这是 某些东西可转换为参考兼容类型的LVALUE。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top