I have faced an interesting dilemma during implementing a custom data structure. Unfortunately I could not found any answer in the C++11 standard, so I hope someone can explain it to me.
There is a class which has a private nested class. Also it uses this private sub-class as a return value in a public function. Like this:
class Enclosing {
private:
// Private nested class
struct Nested {
Nested(int x) : _x(x) {}
int _x;
};
Nested _nested;
public:
Enclosing():_nested(42) {}
// Use private nested class in public interface
const Nested& get_nested() {
return _nested;
}
};
If I try to use call get_nested
it compiles, although I can not create a local variable of type Enclosing::Nested
to store the result. But this is where auto
comes to rescue:
int main() {
Enclosing e;
//Enclosing::Nested n = e.get_ref( ); //Error! Enclosing::Nested is private
auto n = e.get_nested( ); //Ok, unless we name a type
cout << n._x << endl;
}
Even more, with some variadic templates magic I can even call a constructor of the nested class and screate a new exemplar of it:
template<class T, typename... Args>
T* create(const T& t, Args... args) {
return new T(args...);
}
int main() {
Enclosing e;
// We can even create a new instance of the private nested class
auto np = create(e.get_nested( ), 68);
//Enclosing::Nested* np = create(e.get_nested( ), 68); // But don't name a type
cout << np->_x << endl;
}
Could please anybody explain this behavior to me? Why does auto
permit us access to the otherwise private data type? There must be some obvious reason which I just can not see so far. Reference to the paragraph in the Standard is highly welcome.
Thank you very much!
(checked in gcc 4.7.3 and clang 3.2)