it-swarm.com.de

operator << muss genau ein Argument annehmen

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?

72
As As

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);
101
Cat Plus Plus

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;
}
42
Jonathan Wakely

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.

0
Dan Truong