C++ class 模板函数可以访问嵌套的 class 私有成员
C++ class template function can access nested class private member
以下代码无法按预期编译:
#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
}
};
但是,如果我将 EnclosingFun 更改为模板成员函数,编译器 (gcc-7) 不会抱怨访问 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?
}
};
这是 gcc 中的错误吗?或者 c++ 是否有不同的模板成员函数访问规则来访问嵌套的 类?
Is this a bug in gcc? Or does c++ have different access rules for template member function to access nested classes?
也没有。
按照标准,§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.
也就是说,Enclosing::EnclosingFun()
这里没有实例化。向它添加调用会导致它被实例化,然后你会得到错误,例如
prog.cc:8:30: error: 'int Enclosing::Nested::y' is private within this context
std::cout << t << n->y; // OK? Why?
~~~^
这不是 GCC 中的错误。你没有调用你的函数模板,因此函数没有被实例化,它也没有尝试访问嵌套 class 的私有成员。尝试在真实函数(而非模板)中的某处调用您的函数或尝试引用它(隐式实例化)。
A function template by itself is not a type, or a function, or any other entity. No code is generated from a source file that contains only template definitions. In order for any code to appear, a template must be instantiated: the template arguments must be determined so that the compiler can generate an actual function (or class, from a class template).
When code refers to a function in context that requires the function definition to exist, and this particular function has not been explicitly instantiated, implicit instantiation occurs.
template void Enclosing::EnclosingFun(Enclosing::Nested *n, int t); // instantiates the function for the second int parameter
以下代码无法按预期编译:
#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
}
};
但是,如果我将 EnclosingFun 更改为模板成员函数,编译器 (gcc-7) 不会抱怨访问 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?
}
};
这是 gcc 中的错误吗?或者 c++ 是否有不同的模板成员函数访问规则来访问嵌套的 类?
Is this a bug in gcc? Or does c++ have different access rules for template member function to access nested classes?
也没有。
按照标准,§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.
也就是说,Enclosing::EnclosingFun()
这里没有实例化。向它添加调用会导致它被实例化,然后你会得到错误,例如
prog.cc:8:30: error: 'int Enclosing::Nested::y' is private within this context
std::cout << t << n->y; // OK? Why?
~~~^
这不是 GCC 中的错误。你没有调用你的函数模板,因此函数没有被实例化,它也没有尝试访问嵌套 class 的私有成员。尝试在真实函数(而非模板)中的某处调用您的函数或尝试引用它(隐式实例化)。
A function template by itself is not a type, or a function, or any other entity. No code is generated from a source file that contains only template definitions. In order for any code to appear, a template must be instantiated: the template arguments must be determined so that the compiler can generate an actual function (or class, from a class template).
When code refers to a function in context that requires the function definition to exist, and this particular function has not been explicitly instantiated, implicit instantiation occurs.
template void Enclosing::EnclosingFun(Enclosing::Nested *n, int t); // instantiates the function for the second int parameter