¿Por qué puedo usar auto en un tipo privado?

Resuelto hansmaad asked hace 11 años • 5 respuestas

De alguna manera me sorprendió que el siguiente código se compilara y ejecutara (vc2012 y gcc4.7.2).

class Foo {
    struct Bar { int i; };
public:
    Bar Baz() { return Bar(); }
};

int main() {
    Foo f;
    // Foo::Bar b = f.Baz();  // error
    auto b = f.Baz();         // ok
    std::cout << b.i;
}

¿Es correcto que este código se compila bien? ¿Y por qué es correcto? ¿Por qué puedo usarlo autoen un tipo privado y no puedo usar su nombre (como se esperaba)?

hansmaad avatar Nov 23 '12 23:11 hansmaad
Aceptado

Las reglas para la deducción autoson, en su mayor parte, las mismas que para la deducción tipo plantilla. El ejemplo publicado funciona por la misma razón: puede pasar objetos de tipos privados a funciones de plantilla:

template <typename T>
void fun(T t) {}

int main() {
    Foo f;
    fun(f.Baz());         // ok
}

¿Y por qué podemos pasar objetos de tipos privados a funciones de plantilla? Porque sólo el nombre del tipo es inaccesible. El tipo en sí todavía se puede utilizar, por lo que puede devolverlo al código del cliente.

R. Martinho Fernandes avatar Nov 23 '2012 16:11 R. Martinho Fernandes

El control de acceso se aplica a los nombres . Compare con este ejemplo del estándar:

class A {
  class B { };
public:
  typedef B BB;
};

void f() {
  A::BB x; // OK, typedef name A::BB is public
  A::B y; // access error, A::B is private
}
chill avatar Nov 23 '2012 16:11 chill