2012-08-14 10 views
26

En C de BS ++ libro Programming Language (3ª edición), en el capítulo numéricos que muestra el siguiente fragmento de código:¿Cómo toma Stroustrup una referencia no constante a un temporal?

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

El problema es, v_even y v_odd son referencias no constante a los temporales, que no es permitido. Y el intento de compilar este emite un 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)]; 
         ^  ~~~~~~~~~~~~~~~~~~~~~~~~ 

yo nos registramos a través de todas las erratas disponibles en línea y no hay nada que toca este problema fundamental. ¿Me estoy perdiendo de algo? ¿Ha cambiado el lenguaje en este sentido desde que el libro fue impreso (poco probable, ya que el libro mismo menciona la regla contra las referencias no const a los temporales)? ¿Que está pasando aqui?


Si modifico la función para usar valores en lugar de referencias, p. slice_array<double> v_even = ..., entonces esto realmente compila. Sin embargo, resulta que mis encabezados C++ locales hacen que el constructor de copias sea público, mientras que Stroustrup y varias referencias en línea (cppreference.com, cplusplus.com) afirman que el constructor de copias es privado. Supongo que eso significa que esta solución no es portátil. Esto se ve reforzado por el hecho de que Stroustrup enumera explícitamente una muestra de código con variables que no son de referencia y dice que esto produce un error.


La especificación C++ 98 (PDF) declara slice_array<T> como tener un constructor de copia privada. En 2005 (según this spec), y presumiblemente como parte de C++ 03, esto cambió a un constructor de copia pública.

+0

"_El cambio de idioma a este respecto desde que se imprimió el libro_" La regla de enlace de referencia es muy antigua; 'valarray' es más reciente. Parece un error (por BS). – curiousguy

+0

@ curiousguy: El libro ha pasado por 20 impresiones.Miré a través de toda la errata; 2 impresiones hicieron cambios en esta función, pero de manera divertida, el segundo cambio revertió realmente el primero. Y ninguno de los cambios estaba relacionado con el tema en cuestión. –

+2

"_El libro ha pasado por 20 printings._" y comienza a converger? – curiousguy

Respuesta

9

Parece haber un par de problemas diferentes con el ejemplo del código original, y también las declaraciones dadas en el libro para un número de operadores.

El 'mejor' solución creo que es hacer de la siguiente manera

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

Todos los operadores en slice_array<T> se definen como const ya que no están modificando el corte en sí, sino el contenido. Estos se definen incorrectamente en el libro como no const.

4

Esto parece estar publicado en errata (aunque el enlace está muerto ahora).

Sin embargo Google es grande, se muestra un broche de presión para una búsqueda como ésta "slice_array & v_even"

Stroustrup: Errata for 3rd printing of The C++ Programming Language
www.research.att.com/~bs/3rd_printing4.html
[Cached][Share] Shared on Google+.
View the post.
You +1'd this publicly.
Undo

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 ... 

EDIT: - Gracias por editar en cuestión Kevin, no es un error ya que puedo ver en N3092 menciona claramente (§ 26.6.1, Pg 944)

4. Implementations introducing such replacement types shall provide additional functions and operators as follows:
— for every function taking a const valarray&, identical functions taking the replacement types shall be added;
— for every function taking two const valarray& arguments, identical functions taking every combination of const valarray& and replacement types shall be added.

5. In particular, an implementation shall allow a valarray to be constructed from such replacement types and shall allow assignments and computed assignments of such types to valarray, slice_array, gslice_array, mask_array and indirect_array objects.

aún más mi compilador no está dando ningún problema (presentl y VS 2010) con el código, compila perfectamente.

+0

La página a la que se hace referencia es en realidad en vivo [aquí] (http://www.stroustrup.com/3rd_printing4.html), y dice cambiar 'f()' a ... e imprime un duplicado exacto de la función. –

+0

Creo que eso fue actualizado uno, que google almacenado en la caché, puede ser un error (Ctrl + C, Ctrl + V) mientras se desplaza el documento;) – perilbrain

+3

Tenga en cuenta que se sabe que msvc puede tener referencias no constantes a los temporales. – PlasmaHH

Cuestiones relacionadas