Search code examples
c++templatesprivateinstantiation

C++ class template function can access nested class private member


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?


Solution

  • 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?
                               ~~~^
    

    LIVE