Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 443
Lily Ballard Avatar asked Aug 14 '12 06:08

Lily Ballard


People also ask

Can a const reference refer to a non const object?

No. A reference is simply an alias for an existing object.

What is a non const reference C++?

Whether a reference refers to a const or nonconst type affects what we can do with that reference, not whether we can alter the binding of the reference itself." I think this means that making a reference a "const" when it is referenced to a non const object does absolutely nothing.


1 Answers

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

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

All operators on slice_array<T> are defined as const as they are not modifying the slice itself, but the contents. These are defined incorrectly in the book as non-const.

like image 65
Joshua Weinberg Avatar answered Oct 12 '22 08:10

Joshua Weinberg