在Stroustrup的C ++编程语言书(第3版)中,在Numerics一章中,他展示了以下代码片段:
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
是对临时对象的非const引用,这是不允许的。并且尝试编译它会发出错误:
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的一部分,这改为公共拷贝构造函数。
答案 0 :(得分:9)
原始代码示例似乎存在几个不同的问题,以及本书中为许多运营商提供的声明。
我认为应该做的“最佳”解决方案如下
void f(valarray<double>& d)
{
const slice_array<double>& v_even = d[slice(0,d.size()/2,2)];
const slice_array<double>& v_odd = d[slice(1,d.size()/2,2)];
v_odd *= v_even;
v_even = 0;
}
slice_array<T>
上的所有运算符都定义为const
,因为它们不是修改切片本身,而是修改内容。这些在本书中被错误地定义为非const
。
答案 1 :(得分:4)
这似乎是在勘误表中发表的(虽然链接已经死了)。
然而谷歌很棒,它显示了像“slice_array&amp; v_even”这样的搜索的快照
Stroustrup:用于C ++编程的第三次打印的勘误语言
www.research.att.com/~bs/3rd_printing4.html
[缓存] [分享]在Google+上分享。
查看帖子。
你公开为此+1了 撤消
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 *= 2; // double ...
编辑: - 感谢有问题的凯文编辑,这不再是一个错误 我可以在N3092中清楚地看到(§26.6.1,Pg 944)
4. 应提供引入此类替代类型的实施方案 附加功能和操作符如下:
- 适用于每一个 功能采用const valarray&amp;相同的功能 应增加更换类型;
- 每个功能需要两个 const valarray&amp;参数,相同的功能 const valarray&amp;的组合和更换类型 加入。5. 特别是,实现应允许valarray 由这些替换类型构成,并允许分配 并计算这些类型的分配给valarray, slice_array, gslice_array,mask_array和indirect_array对象。
此外,我的编译器没有给出任何问题(目前VS 2010)与代码,编译完美。