How does Stroustrup take a non-const reference to a temporary?

Viewed 1332

In Stroustrup's C++ Programming Language book (3rd edition), in the Numerics chapter he shows the following code snippet:

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;
}

The problem is, v_even and v_odd are non-const references to temporaries, which isn't allowed. And attempting to compile this emits an error:

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)];
                         ^        ~~~~~~~~~~~~~~~~~~~~~~~~

I checked through all of the errata available online and there's nothing that touches upon this fundamental problem. Am I missing something? Did the language change in this regard since the book was printed (unlikely, since the book itself mentions the rule against non-const references to temporaries)? What's going on here?


If I modify the function to use values instead of references, e.g. slice_array<double> v_even = ..., then this actually compiles. However, it turns out my local C++ headers make the copy constructor public, whereas Stroustrup and various online references (cppreference.com, cplusplus.com) claim the copy constructor is private. I assume that means this solution is non-portable. This is reinforced by the fact that Stroustrup explicitly lists a code sample with non-reference variables and says this produces an error.


The C++98 spec (PDF) declares slice_array<T> as having a private copy constructor. By 2005 (according to this spec), and presumably as part of C++03, this changed to a public copy constructor.

2 Answers
Related