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.
There seem to be a couple of different issues with the original code sample, and also the declarations given in the book for a number of operators.
The ‘best’ solution I believe is to do as follows
All operators on
slice_array<T>are defined asconstas they are not modifying the slice itself, but the contents. These are defined incorrectly in the book as non-const.