Domanda

Ho creato una classe Chromosome che alla fine è diventata semplicemente un wrapper per vector con un operatore ostream, quindi ho deciso di digitare invece def vector.Tuttavia, ho problemi con l'operatore ostream basato su modello...È questo il modo migliore per farlo?(Ho visto alcuni approcci e non sono riuscito a farne funzionare nessuno)

template<typename G>
class Chromosome {
 public:
  typedef typename std::vector<G> type;
  typedef typename std::pair<type *,type *> ptr_pair;
};

template<typename G> //line 19 below:
std::ostream& operator<<(std::ostream& os, const Chromosome<G>::type& chromosome) {
  for(auto iter = chromosome.begin(); iter != chromosome.end(); ++iter)
    std::cout << *iter;
  return os;
}

Al momento l'errore che ricevo è:

chromosome.h:19: error: expected unqualified-id before ‘&’ token
chromosome.h:19: error: expected ‘)’ before ‘&’ token
chromosome.h:19: error: expected initializer before ‘&’ token

Saluti.

È stato utile?

Soluzione

Sfortunatamente, non esiste un modo pulito per farlo perché il compilatore non può dedurre il tipo di G dalla dichiarazione della funzione

template<typename G>
std::ostream& operator<<(std::ostream& os, const typename Chromosome<G>::type& chromosome);

Il motivo è che se dovessi specializzarti Chromosome per tipi diversi, potresti ritrovarti in una situazione in cui il compilatore non è in grado di dedurre in modo inequivocabile G.Per esempio:

template <typename G> class Chromosome {
public:
    typedef std::vector<G> type; // No typename needed here, BTW
};

template <> class Chromosome<int> {
public:
    typedef std::vector<double> type;
};

Ora, cosa accadrebbe se facessi questo?

vector<double> v;
cout << v << endl;

Il compilatore non può dire se G È double O int in questo caso, perché entrambi Chromosome<int> E Chromosome<double> Avere vector<double> come tipo nidificato.

Per risolvere questo problema, dovrai utilizzare esplicitamente il tipo vector<G> come argomento:

template<typename G>
std::ostream& operator<<(std::ostream& os, const std::vector<G>& chromosome);

Sfortunatamente, non esiste davvero un modo migliore per farlo.Non è propriamente un difetto del linguaggio, dato che c'è una buona ragione per proibirlo, ma in realtà ti impedisce di fare quello che vuoi in questo contesto.

Altri suggerimenti

Il membro TypeDef type è un nome dipendente: il suo significato dipende dal parametro modello G.È necessario utilizzare un typename per informare il compilatore che type Nomi A Tipo:

const typename Chromosome<G>::type&
.

Per la spiegazione completa, prendere in considerazione la possibilità di leggere la stack overflow C ++ FAQ Articolo, Dove mettere il" modello "e" typename "sui nomi dipendenti .

AS @TemplateTedef allude nei commenti, mentre ciò abiliterà il codice di compilare, non "funzionerà" per consentire di inserire un std::vector<G> in un std::ostream in un type è in un contesto non dedotto.

Il modo più semplice per dichiarare il sovraccarico e ottenere il comportamento previsto è utilizzare std::vector<G> direttamente come tipo argomento:

template<typename G>
std::ostream& operator<<(std::ostream& os, const std::vector<G>& chromosome)
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top