2012-06-07 7 views
11

Supongamos que tengo una clase como esta:¿Por qué no se permite decltype en las variables de miembros privados?

class Foo 
{ 
    std::vector<int> bar; 

public: 
    std::vector<int>& get_bar() { return bar; } 
}; 

y más tarde, quiero otra cosa en algún variables que tiene el mismo tipo que bar. Tendría sentido para mí si pudiera hacer esto:

decltype(Foo::bar) clone_of_bar; 

Pero eso no funciona. El compilador me dice 'std :: vector < int> Foo :: bar' es privado.

Así que terminan por tener que usar algo como esto:

std::remove_reference<decltype(std::declval<Foo>().get_bar())>::type clone_of_bar; 

que funciona, pero parece un completo desastre. Tal vez hay una manera más fácil de hacerlo; No estoy realmente seguro. Pero lo que realmente quiero saber es por qué no puedo usar decltype(Foo::bar). ¿Por qué debería importarle a nadie que bar sea privado? No es como si realmente estuviera accediendo a la variable.

decltype es una nueva característica del idioma. Simplemente no entiendo por qué fue diseñado para no trabajar en variables privadas.

+0

Yo realmente lo apreciaría si usted podría darnos algún ejemplo real ** ** en la que se beneficiaría del uso de decltype de miembros privados. – mfontanini

+0

Bueno, tengo razones realmente sólidas para querer hacer esto. Fue mayormente solo curiosidad. Pero el caso donde traté de usarlo fue este: estaba usando google protobuf, para lo cual defino algunos tipos de eventos y luego protobuf genera algún código para esos tipos. El código generado se parece un poco a lo que escribí en mi ejemplo de pregunta. La cuestión es que quiero poder copiar algunos datos del mensaje protobuf para hacer algunas cosas y no quiero tener que cambiar el código si cambio el tipo en el mensaje protobuf. Entonces eso es lo que quería hacer. No es realmente un gran problema. – karadoc

+0

¿No podría simplemente usar "auto x = somefoo.get_bar();" ? Estarías copiando, sin proporcionar explícitamente el tipo de "x". – mfontanini

Respuesta

17

En términos de abogado de idiomas, bar es un nombre, para usarlo en la expresión decltype, el compilador debe realizar una búsqueda de nombre normal, que respeta el control de acceso.
¿Por qué se debe haber diseñado decltype de manera diferente al resto del lenguaje? No ha presentado ningún argumento convincente sobre por qué no debe ser coherente con, por ejemplo, sizeof.

Como autor de la clase, no quiero que pueda consultar detalles de implementación privados como ese. Si quisiera que el tipo fuera utilizable fuera de la clase, definiría un typedef público que te diga de qué tipo es.

y más tarde, quiero otra cosa en algún variables que tiene el mismo tipo que bar

Quiere "otra variable" que es del mismo tipo que un detalle de implementación privada? Entonces, si el autor de la clase Foo refaciona su código y reemplaza el tipo con algún otro detalle de implementación, repentinamente su código cambia de significado y el código no relacionado puede dejar de compilar repentinamente o silenciosamente tener un comportamiento diferente, porque ese código tontamente confió en detalles privados que no eran de son negocios. ¡Esto introduciría el acoplamiento entre detalles de implementación privada y código no relacionado que el autor de Foo podría no saber que existe! Esa es una idea terrible

+0

Parece una buena idea. ¿Tiene alguna referencia que afirme que este es el caso, por favor? –

+3

Assert what? Esa 'barra' es un nombre y debe encontrarse por búsqueda de nombre? ¿De qué otro modo sabrá el compilador a qué se refiere 'Foo :: bar' en' decltype (Foo :: bar) 'si no hace búsqueda de nombre? –

+2

+1, también sugiriendo usar 'auto clone = foo.get_bar()' o 'decltype (foo.get_bar()) clone' podría ayudar al usuario? – Klaim

9

decltype(Foo::bar)hace funcionan dentro de Foo.

Fuera Foo, ni siquiera estás supone que saben que Foo tiene un elemento llamado bar (eso es lo que private medios), así que por supuesto no debería trabajar.

Cuestiones relacionadas