J'ai été en quelque sorte surpris que le code suivant compile et s'exécute (vc2012 & 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;
}
Est-il correct que ce code se compile correctement? Et pourquoi est-ce correct? Pourquoi puis-je utiliser auto
sur un type privé, alors que je ne peux pas utiliser son nom (comme prévu)?
private
c'est là une commodité pour décrire les API d'une manière que le compilateur peut aider à appliquer. Il n'est pas destiné à empêcher l'accès au type Bar
par les utilisateurs de Foo
, donc il n'empêche Foo
en aucune manière d'offrir cet accès en renvoyant une instance de Bar
.
#include <iostream>
. ;-)
f.Baz().i
c'est également OK, tel quelstd::cout << typeid(f.Baz()).name()
. Le code en dehors de la classe peut "voir" le type renvoyé parBaz()
si vous pouvez le récupérer, vous ne pouvez simplement pas le nommer.