Home > Mobile >  Visibility of private field of a template class from a template function
Visibility of private field of a template class from a template function

Time:10-13

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.

  • Related