operator < debe tomar exactamente un argumento


A. h

#include "logic.h"
...

class A
{
friend ostream& operator<<(ostream&, A&);
...
};

Lógica.cpp

#include "a.h"
...
ostream& logic::operator<<(ostream& os, A& a)
{
...
}
...

Cuando compilo, dice:

Std::ostream& logic::operator

¿Cuál es el problema?

Author: HostileFork, 2012-05-25

3 answers

El problema es que lo define dentro de la clase, que

A) significa que el segundo argumento es implícito (this) y

B) no hará lo que usted quiere que haga, es decir, extender std::ostream.

Tienes que definirlo como una función libre:

class A { /* ... */ };
std::ostream& operator<<(std::ostream&, const A& a);
 96
Author: Cat Plus Plus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-04 10:10:06

Una función amiga no es una función miembro, por lo que el problema es que declaras operator<< como amigo de A:

 friend ostream& operator<<(ostream&, A&);

Luego intenta definirla como una función miembro de la clase logic

 ostream& logic::operator<<(ostream& os, A& a)
          ^^^^^^^

¿Está confundido acerca de si logic es una clase o un espacio de nombres?

El error se debe a que ha intentado definir un miembro operator<< tomando dos argumentos, lo que significa que toma tres argumentos incluyendo el parámetro implícito this. El operador solo puede tomar dos argumentos, por lo que que cuando escribes a << b los dos argumentos son a y b.

Desea definir ostream& operator<<(ostream&, const A&) como una función no miembro, definitivamente no como miembro de logic ya que no tiene nada que ver con esa clase!

std::ostream& operator<<(std::ostream& os, const A& a)
{
  return os << a.number;
}
 41
Author: Jonathan Wakely,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-24 21:13:52

Me encontré con este problema con las clases templadas. Aquí hay una solución más general que tuve que usar:

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

Ahora: * Mi función toString () no puede estar en línea si va a estar escondida en cpp. * Estás atascado con algún código en el encabezado, no pude deshacerme de él. * El operador llamará al método toString (), no está inlineado.

El cuerpo del operador

Tal vez estoy entendiendo mal o falta algo, pero simplemente declarar hacia adelante la plantilla del operador no se vincula en gcc.

Esto también funciona:

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

Creo que también puede evitar los problemas de plantillas forzando declaraciones en encabezados, si usa una clase padre que no está templada para implementar operator

 0
Author: Dan Truong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-27 04:14:02