irappa
irappa

Reputation: 749

template query, accessing private member

I am referring to one of the exercises mentioned in the book "thinking in c++. Below code snippet throws an error for the call h.play, which i understand, because the member i is private. But I was expecting the same error for the call me.play. If i comment the call h.play the code compiles fine. Why there is no error for the call me.play ?

class Buddy {};

template<class T> class My {
  int i;
public:
  void play(My<Buddy>& s) {
    s.i = 3;
  }
};

int main() {
  My<int> h;
  My<Buddy> me, bud;
  h.play(bud);
  me.play(bud);
}

Thankyou.

[Edit] Is there a way to see what code the compiler has generated for

My<int> h and 
My<Buddy> me 

? (anything similar to -E compiler flag) ?

Upvotes: 2

Views: 81

Answers (3)

ScarletAmaranth
ScarletAmaranth

Reputation: 5101

Unlike in languages that just pretend to have strong static type system and generics (looking at you Java), C++ allows you to disambiguate statically parametric types (template types) based on the parameters (the parameters being usually types) the types are templated on.

Note: You can also use a derived (dynamically / late bound) type as a parameter for a statically parametrized type, but it's not relevant in this scenario.

In other words, in C++:

  • typeid(me) == typeid(bud) will be TRUE
  • typeid(h) == typeid(me) will be FALSE

even though the type "My" is the same.

You can access the private data-members from the same type as though they were public, but as you can see, the second comparison is false because the operands are not of the same type, therefore you violate the access restrictions of the type.

Also, I don't think there is any way to take a look at the compiler-generated code. (As far as I know.)

Upvotes: 0

Pubby
Pubby

Reputation: 53067

Members are always "public" to instances of another object with the same type.

Meaning a My<Buddy> instance (such as me) can access private members of another My<Buddy> instance (such as bud).

Keep in mind that My<int> is a completely different type than My<Buddy>, and so it cannot access those members.

Upvotes: 1

Jonathan Potter
Jonathan Potter

Reputation: 37192

Because the play method is defined as taking a reference to My<Buddy> rather than a My<T>, the effective class is the same type when called on another instance of My<Buddy>. Therefore private members are accessible.

Upvotes: 0

Related Questions