The following code fails to compile as expected:
#include<iostream>
class Enclosing {
int x;
class Nested { int y; };
void EnclosingFun(Nested *n) {
std::cout << n->y; // Compiler Error: y is private in Nested
}
};
However, if I change EnclosingFun into a template member function, the compiler (gcc-7) doesn't complain about accessing y:
#include<iostream>
class Enclosing {
int x;
class Nested { int y; };
template <typename T>
void EnclosingFun(Nested *n, T t) {
std::cout << t << n->y; // OK? Why?
}
};
Is this a bug in gcc? Or does c++ have different access rules for template member function to access nested classes?
Is this a bug in gcc? Or does c++ have different access rules for template member function to access nested classes?
No either.
According to the standard, §17.8.1 Implicit instantiation [temp.inst],
An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class, a static data member of a class template, or a substatement of a constexpr if statement ([stmt.if]), unless such instantiation is required.
That means, Enclosing::EnclosingFun()
is not instantiated here. Adding the invocation to it would cause it to be instantiated, then you'll get the error, e.g.
prog.cc:8:30: error: 'int Enclosing::Nested::y' is private within this context
std::cout << t << n->y; // OK? Why?
~~~^