2010-07-17 15 views
11

Se sì, perché? Perché non usa il costruttore di copie del tipo di valore?std :: vector utilizza l'operatore di assegnazione del suo tipo di valore sugli elementi push_back?

ottengo il seguente errore:

/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc: In member functio 
n `ClassWithoutAss& ClassWithoutAss::operator=(const ClassWithoutAss&)': 
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc:238: instantiate 
d from `void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterato 
r<typename _Alloc::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = 
ClassWithoutAss, _Alloc = std::allocator<ClassWithoutAss>]' 
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_vector.h:564: instantia 
ted from `void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = Class 
WithoutAss, _Alloc = std::allocator<ClassWithoutAss>]' 
main.cpp:13: instantiated from here 
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/vector.tcc:238: error: non-st 
atic const member `const int ClassWithoutAss::mem', can't use default assignment 
operator 

g ++ in esecuzione main.cpp il seguente codice:

/* 
* ClassWithoutAss.h 
* 
*/ 

#ifndef CLASSWITHOUTASS_H_ 
#define CLASSWITHOUTASS_H_ 

class ClassWithoutAss 
{ 

public: 
    const int mem; 
    ClassWithoutAss(int mem):mem(mem){} 
    ClassWithoutAss(const ClassWithoutAss& tobeCopied):mem(tobeCopied.mem){} 
    ~ClassWithoutAss(){} 

}; 

#endif /* CLASSWITHOUTASS_H_ */ 

/* 
* main.cpp 
* 
*/ 

#include "ClassWithoutAss.h" 
#include <vector> 

int main() 
{ 
    std::vector<ClassWithoutAss> vec; 
    ClassWithoutAss classWithoutAss(1); 
    (vec.push_back)(classWithoutAss); 

    return 0; 
} 
+13

+1 se solo per 'ClassWithoutAss'. – GManNickG

+2

Perché metti il ​​vec.push_back ... non causerà alcun problema, ma sembra un tantino non necessario ... – Goz

+1

È un "culo" come in "asino"? – sbi

risposta

13

Lo standard C++ 03 dice gli elementi devono essere copia-costruibile e copy- assegnabile per essere utilizzato in un contenitore standard. Quindi un'implementazione è libera di usare quello che vuole.

In C++ 0x, questi requisiti vengono messi su base operativa. (In generale, gli elementi devono essere costruibili e trasferibili.)

Per ottenere ciò che si desidera, è necessario utilizzare un puntatore intelligente come shared_ptr (da Boost, TR1 o C++ 0x) e completamente disabilitare la copia-abilità:

I puntatori possono essere copiati correttamente e il puntatore intelligente assicura che non vi siano perdite. In C++ 0x si può fare meglio con uno std::unique_ptr, sfruttando la semantica del movimento. (In realtà non è necessaria la semantica condivisa, ma in C++ 03 è più semplice così com'è.)

+0

Ti credo, ma puoi spiegare perché i puntatori invece di definire le mie operazioni? Push_backs più rapidi? Quindi non spreco il mio tempo a definire le operazioni? Dovrò guardare in movimento/condividere la semantica. Grazie GMan. Ho solo questi problemi con il tuo aiuto. ;) – user383352

+0

@drenami: cosa intendi? Ho usato i puntatori perché vuoi avere la tua classe nel contenitore, ma non puoi farlo direttamente. Un'astrazione sopra è un puntatore alla tua classe, piuttosto che alla classe stessa. (E i puntatori intelligenti solo per evitare perdite.) – GManNickG

+0

Ma potrei se ho definito un operatore di assegnazione giusto? Quindi la mia domanda è pro/contro dei due progetti - uno senza assegnazione/utilizzo di puntatori, un compito che definisce. Entrambe sono opzioni perché posso scrivere ClassWithAss. – user383352

4

Il problema qui è che i tipi in un contenitore devono essere assegnabili.

Poiché non si definisce un operatore di assegnazione per la classe, il compilatore ne genererà uno. L'operatore di assegnazione di default sarà simile al seguente:

Nella maggior parte dei casi ciò funzionerebbe. Ma il membro mem è un const e quindi non selezionabile. Pertanto la compilazione fallirà nel tentativo di generare l'operatore di assegnazione.

+1

Preferisco le lezioni con 'Ass' – Balk

Problemi correlati