Frage

Ich habe eine Klasse „Chromosom“ erstellt, die letztendlich lediglich ein Wrapper für „Vektor“ mit einem Ostream-Operator war, also habe ich mich stattdessen für „Typedef Vector“ entschieden.Ich habe jedoch Probleme mit dem Ostream-Operator mit Vorlagen ...Ist das der beste Weg?(Ich habe einige Ansätze gesehen und es nicht geschafft, einen zum Laufen zu bringen)

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;
}

Im Moment erhalte ich folgende Fehlermeldung:

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

Prost.

War es hilfreich?

Lösung

Leider gibt es dafür keine saubere Möglichkeit, da der Compiler den Typ nicht ableiten kann G aus der Funktionsdeklaration

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

Der Grund dafür ist, dass man sich spezialisieren würde Chromosome Bei verschiedenen Typen könnte es zu einer Situation kommen, in der der Compiler keine eindeutige Schlussfolgerung ziehen kann G.Zum Beispiel:

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;
};

Was würde nun passieren, wenn Sie das tun würden?

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

Der Compiler kann nicht sagen, ob G Ist double oder int in diesem Fall, weil beides Chromosome<int> Und Chromosome<double> haben vector<double> als ihr verschachtelter Typ.

Um dies zu beheben, müssen Sie den Typ explizit verwenden vector<G> als Argument:

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

Leider gibt es wirklich keine bessere Möglichkeit, dies zu tun.Es handelt sich nicht wirklich um einen Sprachfehler, da es einen guten Grund gibt, ihn zu verbieten, aber er hindert Sie tatsächlich daran, in diesem Zusammenhang das zu tun, was Sie wollen.

Andere Tipps

Die Mitgliedstypdefinition type ist ein abhängiger Name:Seine Bedeutung hängt vom Vorlagenparameter ab G.Sie müssen a verwenden typename um das dem Compiler mitzuteilen type benennt einen Typ:

const typename Chromosome<G>::type&

Eine vollständige Erklärung finden Sie im FAQ-Artikel zu Stack Overflow C++: Wo werden „template“ und „typename“ für abhängige Namen eingefügt?.

Wie @templatetypedef in den Kommentaren andeutet, ermöglicht dies zwar die Kompilierung des Codes, es funktioniert jedoch nicht, Ihnen das Einfügen eines Codes zu ermöglichen std::vector<G> In ein std::ostream Weil type steht in einem nicht abgeleiteten Kontext.

Der einfachste Weg, die Überladung zu deklarieren und das erwartete Verhalten zu erhalten, ist die Verwendung von std::vector<G> direkt als Argumenttyp:

template<typename G>
std::ostream& operator<<(std::ostream& os, const std::vector<G>& chromosome)
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top