2012-08-14 16 views
26

In C di Stroustrup ++ libro Programming Language (3 ° edizione), nel capitolo Numerics mostra il seguente frammento di codice:Come fa Stroustrup a prendere un riferimento non const a un temporaneo?

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

Il problema è, v_even e v_odd sono riferimenti non const a provvisori, che non è permesso. E il tentativo di compilare questo emette un errore:

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

ho controllato attraverso tutti gli errata disponibili on-line e non c'è niente che tocca questo problema fondamentale. Mi sto perdendo qualcosa? La lingua è cambiata in questo senso da quando il libro è stato stampato (improbabile, dal momento che il libro stesso menziona la regola contro i riferimenti non costali ai temporari)? Cosa sta succedendo qui?


Se modifico la funzione per utilizzare valori anziché riferimenti, ad es. slice_array<double> v_even = ..., quindi questo in realtà compila. Tuttavia, le mie intestazioni C++ locali rendono pubblico il costruttore di copie, mentre Stroustrup e vari riferimenti online (cppreference.com, cplusplus.com) sostengono che il costruttore di copie è privato. Presumo che ciò significhi che questa soluzione non è portabile. Ciò è rafforzato dal fatto che Stroustrup elenca esplicitamente un esempio di codice con variabili non di riferimento e dice che questo produce un errore.


Spec C++ 98 (PDF) dichiara slice_array<T> come avere un costruttore di copia privata. Entro il 2005 (secondo this spec) e presumibilmente come parte di C++ 03, questo è cambiato in un costruttore di copie pubbliche.

+0

"_Dato il cambio di lingua in questo senso da quando il libro è stato stampato_" La regola di riferimento è molto vecchia; 'valarray' è più recente. Sembra un errore (di BS). – curiousguy

+0

@curiousguy: il libro ha attraversato 20 stampe.Ho guardato attraverso tutti gli errata; 2 stampe apportate modifiche a questa funzione, ma in modo divertente, il secondo cambiamento effettivamente ripristinato il primo. E nessuno dei due cambiamenti era legato al problema in questione. –

+2

"_Il libro ha attraversato 20 stampe._" e inizia a convergere? – curiousguy

risposta

9

Sembra che ci siano un paio di problemi diversi con l'esempio di codice originale e anche le dichiarazioni fornite nel libro per un numero di operatori.

La soluzione 'migliore' credo è quello di fare la seguente

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

Tutti gli operatori slice_array<T> sono definite come const in quanto non modificano la fetta in sé, ma il contenuto. Questi sono definiti in modo errato nel libro come non-const.

4

Questo sembra essere pubblicato in errata (anche se il collegamento è morto ora).

Tuttavia Google è grande, mostra un gioco da ragazzi per una ricerca come questa "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: - Grazie per modificare in questione Kevin, non è più un errore posso vedere in N3092 chiaramente accennato (§ 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.

ulteriormente il mio compilatore non sta dando alcun problema (presentl y VS 2010) con il codice, compila perfettamente.

+0

Quella pagina di riferimento è in realtà live [qui] (http://www.stroustrup.com/3rd_printing4.html), e dice di cambiare 'f()' a ... e stampa un duplicato esatto della funzione. –

+0

Penso che quella cosa è stata aggiornata una, che in Google memorizzato nella cache, potrebbe essere un errore (Ctrl + C, Ctrl + V) durante lo spostamento del documento;) – perilbrain

+3

Si noti che msvc è noto per essere falsamente in grado di avere riferimenti non-const ai provvisori. – PlasmaHH

Problemi correlati