5

È possibile utilizzare typedef su un contenitore standard senza specializzarlo?Modello typedef per contenitore standard (senza specializzazione)?

codice come questo funziona:

typedef std::vector<int> intVector; 

Ma per questo codice:

template <typename T> 
typedef std::vector<T> DynamicArray<T>; 

ottengo un errore:

template declaration of 'typedef'

E 'possibile fare questo in C++ ??

+0

Considerando che tutto ciò che stai facendo in pratica è rinominare 'std :: vector', quanto sarebbe spiacevole usare' #define DynamicArray std :: vector'? – suszterpatt

+0

@suszterpatt - true, ma cerco di mantenerlo moderno ed evitare l'uso delle macro non sicure :) – dtech

risposta

9

Sì, in C++ 11.

template <typename T> 
using DynamicArray = std::vector<T>; 

(Non che si dovrebbe utilizzare l'alias esatto.)

+0

Non sembra funzionare in Visual Studio 2010 SP1. Ricevo "dichiarazione/definizione modello irriconoscibile" Suppongo che non sia ancora supportato dalla MS? – dtech

+1

@ddriver: no, non lo è. E nemmeno con VC11, AFAIR. Se vuoi C++ 11, usa GCC o Clang. –

+0

Ho trovato una soluzione alternativa per VS semplicemente ereditando il vettore. Per favore vedi la risposta che ho aggiunto e fai un po 'di luce se questa non è una buona idea. Grazie! – dtech

2

La soluzione comune (se non si utilizza C++ 11) è di fare questo:

template<class T> 
struct DynamicArray 
{ 
    typedef std::vector<T> Type; 
}; 

e usarlo come DynamicArray<Something>::Type.

6

Se il supporto del compilatore C++ 11:

template <typename T> 
using DynamicArray = std::vector<T>; 

altrimenti (C++ 98 anni o più) è possibile utilizzare una struttura di aiuto come il seguente

template<typename T> 
struct DynamicArray 
{ 
    typedef std::vector<T> type; 
}; 

e quindi utilizzare come

DynamicArray<int>::type my_array; 

Ereditare da std :: vector è una possibile soluzione ma tenere presente che i contenitori STL non hanno un distruttore virtuale. Vale a dire:

template <typename T> 
struct DynamicArray: vector<T> { ... }; 

int main() { 
    vector<int>* p = new DynamicArray<int>(); 
    delete p; // this is Undefined Behavior 
    return 0; 
} 
+0

Sì, ma perché allocare dinamicamente un vettore quando utilizza internamente l'allocazione dinamica della memoria per i suoi dati? – dtech

+0

Inoltre, non posso scrivere da solo un distruttore, penso che il distruttore del vettore debba essere responsabile dei suoi dati, devo solo occuparmi di cose extra che ho aggiunto. Potrei sbagliarti, non sono troppo bravo con il C++. – dtech

+0

Voglio dire, certo, potrebbero esserci problemi con l'uso di polimorfismi, ma dato che l'intento è quello di usare solo la classe derivata, non penso ci saranno problemi a causa della mancanza di distruttore virtuale. Voglio dire, non è che chiamerò delete su un puntatore al vettore che in realtà punta a un DynamicArray, che non ha nemmeno membri extra dinamicamente allocati per richiedere un'attenzione particolare. Perfavore, correggimi se sbaglio. Grazie! – dtech

3

Questa sintassi non è valida in C++, non esiste alcuna funzione come "modello typedef".

template <typename T> 
typedef std::vector<T> DynamicArray<T>; 

Tuttavia, C++ 11 introduce una sintassi modello di alias che è quasi simile a questo:

template <typename T> 
using DynamicArray = std::vector<T>; 

In C++ 03 è possibile utilizzare un modello metafunction come:

template<class T> 
struct DynamicArray 
{ 
    typedef std::vector<T> type; 
}; 
0

per aggiungere la mia soluzione al mix

dal momento che la funzione C++ 11 non è supportato da Visual Studio ho deciso di appena ereditare std :: vector, usando questo per aggiungere alcune funzionalità:

template <typename T> 
class DynamicArray : public std::vector<T> { 
public: 
    DynamicArray& operator<<(const T& value) 
    { 
     push_back(value); 
     return *this; 
    } 
}; 

Ora oltre push_back, concatenamento è supportato anche:

DynamicArray<int> array; 
array << 1 << 2 << 3 << 4 << 5 << 6; 

Non so se un tale approccio può avere degli svantaggi non intenzionali , quindi se ne conosci qualcuno, per favore condividili!

+1

Ereditare da contenitori standard ha alcuni inconvenienti ... (conf. La mia risposta) Hai preso in considerazione l'implementazione di funzioni gratuite? 'DynamicArray & operator << (const DynamicArray & arr, const T & value)' – log0

Problemi correlati