2010-04-27 14 views
7

De repente, en this article ("problem 2") Veo una afirmación de que C++ Standard prohíbe el uso de contenedores STL para almacenar elemants de clase si esa clase tiene una sobrecarga operator&().¿Por qué el operador de sobrecarga y() está prohibido para las clases almacenadas en contenedores STL?

Después de haber sobrecargado operator&()can indeed be problematic, pero se parece a un defecto "dirección de" operador puede ser utilizado fácilmente por a set of dirty-looking casts that are used in boost::addressof() y se cree que son portátiles y estándar-compilant.

¿Por qué está sobrecargado operator&() prohibido para las clases almacenadas en contenedores STL mientras existe la solución boost::addressof()?

+0

Por curiosidad (sin crítica, realmente solo curiosidad), ¿dónde sobrecargarías el operador de dirección? – falstro

+1

@roe: en clases como ATL :: CComPtr (http://msdn.microsoft.com/en-us/library/ezzw7k98(VS.80).aspx) que hace sentido. A menudo los usa en lugar de punteros crudos.Desea que las llamadas funcionen como 'HRESULT GetStuff (IInterface **)' en CComPtr y que requiera un método para recuperar la dirección del puntero encapsulado o del operador sobrecargado &() '. – sharptooth

+1

Después de un rápido recorrido al capítulo sobre contenedores en el estándar, no he encontrado tal reclamo. Descargo de responsabilidad: Acabo de hojear, me podría haber perdido si no estaba en negrita y/o al principio de la oración :) –

Respuesta

6

Sin haber mirado los enlaces, supongo que los trucos en boost::addressof() se inventaron bien después del requisito de no sobrecargar el prefijo único & para los objetos que se guardarán en los contenedores de la lib estándar.

Recuerdo vagamente a Pete Becker (que en ese momento trabajaba para Dinkumware en su implementación de biblioteca estándar) que todos los que sobrecargaban el operador de dirección y esperaban que la implementación de su biblioteca estándar siguiera funcionando debía sancionarse al implementar una biblioteca estándar que hace esto

+0

Hace que uno se pregunte por qué sobrecargar el operador de la dirección de entrada está permitido en primer lugar, ¿o no? –

+3

@MadKeithV: Cuando la sobrecarga del operador fue "inventada" para C++, se tuvo que decidir qué operadores deberían poder cargarse y cuáles no. Como no había ninguna experiencia en ese momento, al menos no con C++, tenía que adivinarse. En retrospectiva, es fácil criticar estas conjeturas. (Aunque, dado que se usa de hecho, hay personas que argumentarían que sobrecargar el prefijo unario '&' es útil y beneficioso). – sbi

2

Probablemente porque es menos complicado prohibir el uso de operadores sobrecargados &() que crear una función std :: addressof() y reemplazar cada uso de & en código de contenedor con ella.

+0

El equipo VS2010 estaba trabajando de nuevo en todo el STL. Eso no es un argumento De acuerdo con la publicación mencionada, es un comportamiento indefinido. (-1) – xtofl

+1

¿El equipo de VS2010 especifica el estándar C++, pensé que era más una cuestión de por qué el estándar es lo que es? La otra respuesta es probablemente mejor de todos modos, que es algo histórico. – identitycrisisuk

1

El estándar se finalizó en 1998 con correcciones en el 2003, mientras que boost::addressofdates to principios de 2002.

Por otra parte, no está claro que addressof es la respuesta. Las sobrecargas de operator&() indican que se supone que se deben evitar los punteros crudos. El miembro Allocator::address proporciona la mejor interfaz para obtener desde Allocator::reference hasta Allocator::pointer, por lo que, en teoría, debería ser capaz de introducir y anular operator& una clase que por lo demás se comporta bien con un asignador personalizado.

Teniendo en cuenta que las referencias hacen casi todo lo que hacen los punteros, y la interfaz de Allocator abstrae todo lo demás, no debería haber necesidad de punteros crudos.

La conveniencia de los implementadores de la biblioteca no debería ser un problema. La semántica mal definida de Allocator::pointer es un problema, y ​​lo que he leído hasta ahora en C++ 0x no lo aclara.

C++ 0x elimina cualquier mención de operator& de CopyConstructible, y además no requiere nada -constructible para argumentos de contenedor en absoluto- el usuario puede apegarse a emplace. Incluso vector solo requiere Destructible, aunque supongo que usar insert o erase requeriría más.

(Tenga en cuenta que, en la lectura más estricta, sobrecargas no son prohibidos en C++ 03. Usted simplemente no permite cambiar el valor o el tipo de la orden interna.)

+0

"_El estándar se finalizó en 1998_" en 1997. – curiousguy

Cuestiones relacionadas