c++ - Stroustrup 如何对临时对象进行非常量引用?

标签 c++ reference language-lawyer

在 Stroustrup 的 C++ 编程语言书(第 3 版)中,在数值章节中,他展示了以下代码片段:

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_evenv_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)声称复制构造函数是私有(private)的。我认为这意味着这个解决方案是不可移植的。 Stroustrup 明确列出了一个带有非引用变量的代码示例并说这会产生错误,这一事实进一步加强了这一点。


C++98 规范 (PDF) 声明 slice_array<T>就像拥有一个私有(private)复制构造函数一样。到 2005 年(根据 this spec ),大概是作为 C++03 的一部分,这变成了公共(public)复制构造函数。

最佳答案

原始代码示例似乎存在几个不同的问题,而且书中为许多运算符提供的声明也存在。

我认为“最佳”解决方案如下

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 .

关于c++ - Stroustrup 如何对临时对象进行非常量引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11946711/

相关文章:

c++ - 为什么不同类型的变量声明表示不同的实体

c++ - 在 C++ 中追加不同的字段

python - 在pybind11中输入npz文件

c++ - 在复制初始化中是否返回对本地对象未定义行为的引用?

string - 存储字符串引用

c++ - C++ 语法演化是如何管理的?

c - 为什么转换 (unsigned long long)DBL_MAX(或 FLT_MAX)也会导致 FE_INEXACT 升高?

c++ - 如何禁用或重新路由 ALSA lib 日志记录

c++ - SFML 2.0 崩溃(window-d-2 错误

Java:需要对引用对象的 API 文档进行说明