ah
#include "logic.h"
...
class A
{
friend ostream& operator<<(ostream&, A&);
...
};
logic.cpp
#include "a.h"
...
ostream& logic::operator<<(ostream& os, A& a)
{
...
}
...
Wenn ich kompiliere, heißt es:
std :: ostream & logic :: operator << (std :: ostream &, A &) muss genau ein Argument annehmen.
Worin besteht das Problem?
Das Problem ist, dass Sie es innerhalb der Klasse definieren, welche
a) bedeutet, das zweite Argument ist implizit (this
) und
b) es wird nicht das tun, was Sie möchten, nämlich std::ostream
erweitern.
Sie müssen es als freie Funktion definieren:
class A { /* ... */ };
std::ostream& operator<<(std::ostream&, const A& a);
Eine Friend-Funktion ist keine Member-Funktion, daher besteht das Problem darin, dass Sie operator<<
als Freund von A
deklarieren:
friend ostream& operator<<(ostream&, A&);
versuchen Sie dann, es als Member-Funktion der Klasse logic
zu definieren.
ostream& logic::operator<<(ostream& os, A& a)
^^^^^^^
Sind Sie verwirrt, ob logic
eine Klasse oder ein Namespace ist?
Der Fehler ist darauf zurückzuführen, dass Sie versucht haben, ein Element operator<<
mit zwei Argumenten zu definieren. Dies bedeutet, dass drei Argumente einschließlich des impliziten Parameters this
erforderlich sind. Der Operator kann nur zwei Argumente verwenden, sodass beim Schreiben von a << b
die beiden Argumente a
und b
sind.
Sie möchten ostream& operator<<(ostream&, const A&)
als non - Member-Funktion definieren, definitiv nicht als Member von logic
, da es nichts mit dieser Klasse zu tun hat!
std::ostream& operator<<(std::ostream& os, const A& a)
{
return os << a.number;
}
Ich bin auf dieses Problem mit vorgefertigten Klassen gestoßen ... Hier eine allgemeinere Lösung, die ich verwenden musste:
template class <T>
class myClass
{
int myField;
// Helper function accessing my fields
void toString(std::ostream&) const;
// Friend means operator<< can use private variables
// It needs to be declared as a template, but T is taken
template <class U>
friend std::ostream& operator<<(std::ostream&, const myClass<U> &);
}
// Operator is a non-member and global, so it's not myClass<U>::operator<<()
// Because of how C++ implements templates the function must be
// fully declared in the header for the linker to resolve it :(
template <class U>
std::ostream& operator<<(std::ostream& os, const myClass<U> & obj)
{
obj.toString(os);
return os;
}
Nun: * Meine toString () - Funktion kann nicht inline sein, wenn sie in cpp . Verstaut wird. * Sie haben etwas Code in der Kopfzeile, ich konnte ihn nicht loswerden . * Der Operator ruft die toString () -Methode auf, sie ist nicht inline.
Der Operator-Operator << kann in der friend-Klausel oder außerhalb der Klasse deklariert werden. Beide Optionen sind hässlich. :(
Vielleicht missverstehe ich oder vermisse etwas, aber das Vorwärts-Deklarieren der Operator-Vorlage ist in gcc nicht verlinkt.
Das funktioniert auch:
template class <T>
class myClass
{
int myField;
// Helper function accessing my fields
void toString(std::ostream&) const;
// For some reason this requires using T, and not U as above
friend std::ostream& operator<<(std::ostream&, const myClass<T> &)
{
obj.toString(os);
return os;
}
}
Ich denke, Sie können auch die Vorlagenprobleme vermeiden, die Deklarationen in Headern erzwingen, wenn Sie eine übergeordnete Klasse verwenden, für die der Operator << nicht implementiert ist, und eine virtuelle toString () -Methode verwenden.