【发布时间】:2012-08-10 09:57:14
【问题描述】:
在 Stroustrup 的 C++ Programming Language book(第 3 版)中,在 Numerics 章节中,他展示了以下代码 sn-p:
void f(valarray<double>& d)
{
slice_array<double>& v_even = d[slice(0,d.size()/2,2)];
slice_array<double>& v_odd = d[slice(1,d.size()/2,2)];
v_odd *= v_even;
v_even = 0;
}
问题是,v_even 和 v_odd 是对临时对象的非常量引用,这是不允许的。并尝试编译它会发出错误:
error: non-const lvalue reference to type 'slice_array<double>' cannot bind to a temporary of type 'slice_array<double>'
slice_array<double>& v_even = d[slice(0,d.size()/2,2)];
^ ~~~~~~~~~~~~~~~~~~~~~~~~
我检查了所有在线可用的勘误表,没有任何内容涉及这个基本问题。我错过了什么吗?自从这本书出版以来,这方面的语言是否发生了变化(不太可能,因为这本书本身提到了反对非常量引用临时变量的规则)?这是怎么回事?
如果我修改函数以使用值而不是引用,例如slice_array<double> v_even = ...,然后这实际上编译。然而,事实证明我的本地 C++ 头文件使复制构造函数公开,而 Stroustrup 和各种在线参考(cppreference.com、cplusplus.com)声称复制构造函数是私有的。我认为这意味着这个解决方案是不可移植的。 Stroustrup 明确列出了一个带有非引用变量的代码示例并表示这会产生错误,这一事实进一步强化了这一点。
C++98 规范 (PDF) 将 slice_array<T> 声明为具有私有复制构造函数。到 2005 年(根据 this spec),大概是作为 C++03 的一部分,它变成了一个公共复制构造函数。
【问题讨论】:
-
"这本书出版后语言有没有变化" 参考绑定规则很老了;
valarray较新。它看起来像一个错误(由 BS)。 -
@curiousguy:这本书已经印刷了 20 次。我浏览了所有的勘误表;两次印刷对该功能进行了更改,但有趣的是,第二次更改实际上恢复了第一次。而且这两种变化都与手头的问题无关。
-
"这本书已经印刷了 20 次。" 开始收敛了?
-
它also surprised me 学习 Stroustrup 并不完美,我知道。
-
@Anonymous:多么令人难以置信的冒犯、冒昧和无知。
标签: c++ reference language-lawyer