2013-11-09 17 views
6
tipi

standard C++ come int o char avere ctors, in modo da poter avere espressioni come:Passando una variabile anonima per riferimento

tipi
int a = int(67); // create anonymous variable and assing it to variable a 
int b(13);  // initialize variable b 
int(77);   // create anonymous variable 

definito dall'utente (strutture o classi) sono in grado di fare lo stesso:

struct STRUCT 
{ 
    STRUCT(int a){} 
}; 

STRUCT c = STRUCT(67); 
STRUCT d(13); 
STRUCT(77); 

La domanda è: perché possiamo passare da una struttura anonima di riferimento o da istanze di classe, ma non possiamo passare i tipi standard?

struct STRUCT 
{ 
    STRUCT(int a){} 
}; 

void func1(int& i){} 
void func2(STRUCT& s){} 
void func3(int i){} 
void func4(STRUCT s){} 

void main() 
{ 
    //func1(int(56)); // ERROR: C2664 
    func2(STRUCT(65)); // OK: anonymous object is created then assigned to a reference 
    func3(int(46)); // OK: anonymous int is created then assigned to a parameter 
    func4(STRUCT(12)); // OK: anonymous object is created then assigned to a parameter 
} 
+4

La riga 'func2' non deve essere compilata (per lo stesso motivo della prima). – Mat

+0

'void main()' non è standard. –

+0

Con un livello di avviso appropriato, si otterrà l'avvertenza C4239: estensione non standard utilizzata: 'argomento': conversione da 'STRUCT' a 'STRUCT &'; Un riferimento non const può essere associato a un lvalue'. Dovresti usare '/ W4'. –

risposta

2

Se il compilatore lo consente, non è un compilatore C++ compatibile standard. Non è possibile associare un valore provvisorio a un riferimento a valore non costante. È la regola. Sia clang e gcc non compili quel codice per func2(STRUCT(65));.

Invece si hanno alternative:

void func1(int&& i){} 

void func1(const int& i){} 

Legacy da C++ 03: A (lvalue) riferimento ad un tipo non-const (int &i) dovrebbe in grado di modificare il parametro poi passando un oggetto temporaneo, quali come 56 non è logico perché non modificabile. Un riferimento a un tipo const (const int &i) si suppone solo osservare il valore come di sola lettura, quindi passare un valore temporaneo come 52 è legale.

In C++ 11 è possibile fare riferimento a un oggetto temporaneo non costante mediante &&.

5

Sembra che si stia utilizzando il compilatore MS VC++ che presenta tale errore. :) È necessario associare l'oggetto temporaneo con riferimento const. Ad esempio si può scrivere

const int &ri = 10; 

ma non si può scrivere

int &ri = 10; 

Lo stesso vale per i tipi definiti dall'utente.

const STRUCT &rs = STRUCT(10); 

STRUCT &rs = STRUCT(10); // the compiler shall issue an error. 
0

in C++, un oggetto temporaneo anonimo è sempre un right-value.To accettare un diritto-valore come argomento, è possibile:

1) foo1 .void (TIPO); // passaggio per valore
2) .void foo2 (const TYPE &); // passando con riferimento const
3) .void foo3 (TYPE & &); // in C++ 11, passando per il riferimento al valore di destra

I tuoi "func3" e "func4" accettano un argomento passato come valore, è ok.
Tuttavia, "func1" e "func2" possono solo accettare un argomento passato da un riferimento a valore di sinistra. È sbagliato passare un parametro anonimo.

Problemi correlati