|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Jan 2012
Messaggi: 1267
|
[C++] Template function dentro a una classe
Ciao,
ho una classe che contiene questi typedef: Codice:
classe MyVector { public: // ****************** Typedefs for the user typedef double value_type; typedef double& reference; typedef const double& const_reference; typedef double* iterator; typedef const double* const_iterator; typedef std::size_t size_type; typedef std::ptrdiff_t difference_type; }; Codice:
MyVector(size_type n, const double* array); Codice:
// Private function for memory management: create a BbVector by copying another BbVector using iterators (similar to one of std::vector constructors) void MyVector::create(const_iterator b, const_iterator e) { mySize = e - b; myVector = alloc.allocate(mySize + 1); start = myVector + 1; limit = avail = start + mySize; uninitialized_copy(b, e, start); } Ho un altro costruttore, che prende uno std::vector: Codice:
BbVector::BbVector(const vector<double>& vec) { size_type n = vec.size(); if (n == 0) { create(); } else { create(vec.cbegin(), vec.cend()); } } typedef __gnu_cxx::__normal_iterator<const_pointer, vector> const_iterator, con tutti i typedef del caso... Allora ho pensato di rendere create una funzione template, scrivendo: Codice:
template<class C> void BbVector::create(typename C::const_iterator b, typename C::const_iterator e) { mySize = e - b; myVector = alloc.allocate(mySize + 1); start = myVector + 1; limit = avail = start + mySize; uninitialized_copy(b, e, start); } Codice:
create<const double*>(array, array + n); L'unico modo per farla funzionare quando la invoco passandogli l'array di double è: Codice:
create<MyVector>(array, array + n); Qualcuno sa suggerirmi una soluzione migliore? Ho appena cominciato a studiare i template in modo approfondito, e sono un po' spaesato ![]() |
![]() |
![]() |
![]() |
#2 | |
Member
Iscritto dal: Jul 2012
Messaggi: 91
|
Quote:
Cioè Codice:
template <typename T> void BbVector::create(T b, T e) { //bla bla bla } create<const double*>(...) create<std::vector<double>::const_iterator>(...) |
|
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Jan 2012
Messaggi: 1267
|
Quote:
Cmq non mi pare la soluzione giusta in quanto non avrei controllo su cosa viene passato alla funzione. Quei T finiscono a std::uninitialized_copy, quindi devono essere dei puntatori. Se però scrivo il template in questo modo, non ho alcun filtro: potrei scrivere Codice:
bool a, b; create(a, b); ![]() ![]() |
|
![]() |
![]() |
![]() |
#4 |
Member
Iscritto dal: Jul 2012
Messaggi: 91
|
Non ho provato ma non dovrebbe compilare proprio perchè non compilerebbe unitialized_copy!
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Jan 2012
Messaggi: 1267
|
|
![]() |
![]() |
![]() |
#6 |
Member
Iscritto dal: Jul 2012
Messaggi: 91
|
In generale puoi fare un controllo a compile time tramite una classe "traits" che definisce le caratteristiche che deve avere la tua classe parametro.
In questo caso uninitialized_copy utilizza iterator_traits che è naturalmente definita per gli iteratori ed ha una specializzazione per i tipi puntatore (T* e const T*) Se volessi usare un'altro tipo di iteratore che non rientra nelle casistiche predefinite basterebe scrivere una tua specializzazione di iterator_traits. |
![]() |
![]() |
![]() |
#7 | |
Senior Member
Iscritto dal: Jan 2012
Messaggi: 1267
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 00:58.