I have a template class
template<class T>
class MyClass
{
public:
MyClass() { privateField = 0; };
T getPrivateField() {
return privateField;
}
private:
T privateField;
};
and a template function which takes an instance of MyClass as a parameter
template<class T>
T foo(MyClass<T> mc) {
return mc.privateField;
}
I was confused by the fact that I can see a private field of MyClass in template function, but can't actually use it.
Here is an example of field visibility(screenshot)
Question:
Why can I see a private field of MyClass exactly in a template function and how can I disable it in my code(if it's possible)? Or it's just like a feature from Visual Studio?
CodePudding user response:
private
will limit your code's access to a member.
It does not make parts of your code invisible to tools that might make observations about what you have written. It's not private in the sense that a personal password might be private.
CodePudding user response:
private
does not mean that it is completely hidden from the outside, or that nobody outside of the class should be aware that it exists.
Consider this example:
#include <iostream>
struct foo {
int x = 0;
};
struct bar : foo {
private:
int x = 0;
};
int main() {
bar b;
b.x = 0;
}
Now suppose, main
was written by a user who only knows about the public parts of the involved classes. They would have no way to understand why they get the error message:
<source>: In function 'int main()':
<source>:15:7: error: 'int bar::x' is private within this context
15 | b.x = 0;
| ^
<source>:10:13: note: declared private here
10 | int x = 0;
| ^
Admittetly this is a made up example, and bar
can be considered broken. The point is just that your IDE would not necessarily do you a favor if it would not show any private members. Their presence or absence can change the meaning of code that is written only against the public interface.
CodePudding user response:
Do not confuse visibility with access.
Consider how overload resolution behaves:
class X {
private:
void f(int value);
public:
void f(double value);
};
If we try to call X::f() with an int from outside:
int main() {
X obj;
obj.f(1234);
}
We still get the error:
<source>:10:15: error: 'void X::f(int)' is private within this context
obj.f(1234);
We definitely would not want main to call X::f(double) simply because it could not access the X::f(int) function. Otherwise, access could literally change the runtime meaning of your program.
C will
- build an overload set from name lookup
- perform resolution to pick the best match
- verify access
In that order. That is, access is checked after the overload resolution has completed.