sobrecarga relacionales operadores operador matrices herencia funciones codigo clases c++ gcc

c++ - relacionales - "No se puede reenviar declarar clases que sobrecargan el operador &"?



sobrecarga de operadores relacionales en c++ (6)

5.3.1 del Estándar tiene "Se puede tomar la dirección de un objeto de tipo incompleto, pero si el tipo completo de ese objeto es un tipo de clase que declara el operador & () como una función miembro, entonces el comportamiento no está definido (y no se requiere diagnóstico) ".

Yo tampoco sabía esto, pero como ha señalado otro afiche, es fácil ver cómo podría causar que un compilador genere código incorrecto.

En la Guía de estilo de Google C ++, hay una sección sobre Sobrecarga del operador que tiene una curiosa declaración:

La sobrecarga también tiene ramificaciones sorprendentes. Por ejemplo, no puede reenviar clases declaradas que sobrecargan el operator& .

Esto parece incorrecto, y no he podido encontrar ningún código que cause que GCC tenga un problema con él. ¿Alguien sabe a qué se refiere esa afirmación?


Tampoco había oído hablar de él, pero esto da resultados potencialmente confusos para el mismo código antes y después de la sobrecarga:

#include <iostream> class Foo; void bar (Foo& foo) { std::cout << &foo << std::endl; } class Foo { public: bool operator & () { return true; } }; void baz (Foo& foo) { std::cout << &foo << std::endl; } int main () { Foo foo; bar(foo); baz(foo); return 0; }

salida:

0x7fff092c55df 1

Aunque hay otras razones por las que no harías eso de todos modos, la dirección de sobrecarga no funciona muy bien con stl o código genérico.


Creo que la declaración no es precisa. Al igual que las otras respuestas, estoy adivinando aquí. Primero, supongo que se están refiriendo al operador unario y no al operador binario . Es decir:

int x = 5; int* p = &x; // unary & if (x & 1) // binary &

Puede reenviar declarar cualquier clase que desee. Sin embargo, si la clase sobrecarga el operador unario &, y llama al operador unario & en un puntero a uno de esos objetos, probablemente obtendrá un comportamiento incoherente (a veces simplemente obtendrá la dirección, y algunas veces llamará al método sobrecargado). Esto podría convertirse fácilmente en algo casi imposible de depurar.

Me alegro de que Fizzer haya mirado el estándar y no haya adivinado.


Debido a la capacidad de sobrecargar al operador, la biblioteca de impulso ofrece la útil dirección de plantilla de () para buscar la dirección real de una clase. No es que sugiera que sobrecargue el operador &, pero si lo necesita, hay ayuda disponible.


La redacción no está clara, por supuesto, puedes anunciar la clase, pero la regla obviamente está tomando la posición que "no deberías" cuando la clase sobrecarga al operator& .

Reglas similares también están presentes en otros estándares de codificación, por ejemplo, la regla 159 de JSF (pdf) establece que el operator& no debe estar sobrecargado.


Editado para dar cuenta de los comentarios:

Esto es una suposición, pero una de las principales razones para reenviar declarar es poder declarar punteros a esa clase. El compilador debe hacer suposiciones sobre la clase antes de tener la definición, por ejemplo, el tamaño de los punteros.

¿Es posible cambiar el tamaño de T * al sobrecargar al operador y por T? (EDITAR: los que comentan, y creo que no), pero

¿Qué supuesto se viola al sobrecargar al operador? ¿Cómo cambia la clase?

Aquí hay una manera.

Podría escribir:

class A; void f(A& x) { A* xPointer = &x; }

Eso tiene un nuevo significado si el operador & () está sobrecargado que si no, y el compilador puede pensar que puede generar código para él, pero sería incorrecto.