By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,655 Members | 964 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,655 IT Pros & Developers. It's quick & easy.

portected access: template derivation vs. class derivation

P: n/a
In the following code, the class B will not compile if the function da is
uncommented. I took exactly the same code, and turned it into templates.
Never used the template parameter in anything but the baseclass name in the
derived class, and the code compiles without any complaints about protected
access. Why? What is different about the templated code?

class A{
public:
A(const int& x_=0): x(x_){}
protected:
int x;
};

class B: public A{
public:
B(const int& x_=0): A(x_){}
/*
B& da(const int& da_)
{
this->a.x += da_; // error: protected access
return *this;
}
*/
protected:
A a;
};

/*Same as above but with templates*/
template<typename T>
class AT{
public:
AT(const int& x_=0): x(x_){}
protected:
int x;
};

template<typename T>
class BT: public AT<T>{
public:
BT(const int& x_=0): AT<T>(x_){}

BT& da(const int& da_)
{
this->a.x += da_; // works fine
return *this;
}

protected:
AT<T> a;
};

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #1
Share this Question
Share on Google+
12 Replies


P: n/a
Steven T. Hatton wrote:
In the following code, the class B will not compile if the function da is
uncommented. I took exactly the same code, and turned it into templates.
Never used the template parameter in anything but the baseclass name in the
derived class, and the code compiles without any complaints about protected
access. Why? What is different about the templated code?
The templated code is not really "compiled" unless you attempt to
instantiate the template. Did you? Where is the rest of the code?
Was there anything else? If there wasn't, then all the compiler did
for your templates was checking the syntax. Names were not resolved,
access rights weren't checked, etc.

class A{
public:
A(const int& x_=0): x(x_){}
protected:
int x;
};

class B: public A{
public:
B(const int& x_=0): A(x_){}
/*
B& da(const int& da_)
{
this->a.x += da_; // error: protected access
return *this;
}
*/
protected:
A a;
};

/*Same as above but with templates*/
template<typename T>
class AT{
public:
AT(const int& x_=0): x(x_){}
protected:
int x;
};

template<typename T>
class BT: public AT<T>{
public:
BT(const int& x_=0): AT<T>(x_){}

BT& da(const int& da_)
{
this->a.x += da_; // works fine
return *this;
}

protected:
AT<T> a;
};


V
Jul 22 '05 #2

P: n/a

"Steven T. Hatton" <su******@setidava.kushan.aa> wrote in message
news:uI********************@speakeasy.net...
In the following code, the class B will not compile if the function da is uncommented. I took exactly the same code, and turned it into templates. Never used the template parameter in anything but the baseclass name in the derived class, and the code compiles without any complaints about protected access. Why? What is different about the templated code?


Try compiling your code with this main function:

int main()
{
BT<int> b;
b.da(int());
}

You should get the same error. The reason the templated version
compiles in your original that dependent names (such as this->a)
aren't looked up until instantiation, and that no instantation occurs
in your example.

Jonathan
Jul 22 '05 #3

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:SS*************@newsread1.dllstx09.us.to.veri o.net...
Steven T. Hatton wrote:
The templated code is not really "compiled" unless you attempt to
instantiate the template. Did you?
So is the dependent/non-dependent distinction a red herring here?
Where is the rest of the code?
Was there anything else? If there wasn't, then all the compiler did
for your templates was checking the syntax. Names were not resolved, access rights weren't checked, etc.


Jonathan
Jul 22 '05 #4

P: n/a
Steven T. Hatton wrote:
In the following code, the class B will not compile if the function da is
uncommented. I took exactly the same code, and turned it into templates.
Never used the template parameter in anything but the baseclass name in
the derived class, and the code compiles without any complaints about
protected
access. Why? What is different about the templated code?

class A{
public:
A(const int& x_=0): x(x_){}
protected:
int x;
};

class B: public A{
public:
B(const int& x_=0): A(x_){}
/*
B& da(const int& da_)
{
this->a.x += da_; // error: protected access
return *this;
}
*/
protected:
A a;
};

/*Same as above but with templates*/
template<typename T>
class AT{
public:
AT(const int& x_=0): x(x_){}
protected:
int x;
};

template<typename T>
class BT: public AT<T>{
public:
BT(const int& x_=0): AT<T>(x_){}

BT& da(const int& da_)
{
this->a.x += da_; // works fine
return *this;
}

protected:
AT<T> a;
};


Hi,
did you actually instantiate the template in main(), or did you just
compile this file as a compilation unit? In the later case, it would be
unwise for the compiler to complain: If this template is used as part of a
bigger programm, some other part might provide a specialization for AT<>
where the member x is not protected. For those types, BT<> should not cause
any troubles at all. Beware that the interface of AT<T> may depend on T.

Rest assured, you will see tons of inscrutable error messages when you
actually instantiate the template so that access violations happen.
Best

Kai-Uwe Bux
Jul 22 '05 #5

P: n/a
Jonathan Turkanis wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:SS*************@newsread1.dllstx09.us.to.veri o.net...
Steven T. Hatton wrote:

The templated code is not really "compiled" unless you attempt to
instantiate the template. Did you?

So is the dependent/non-dependent distinction a red herring here?


I am not sure I understand the question. Could you rephrase it?

V
Jul 22 '05 #6

P: n/a
Victor Bazarov wrote:
Steven T. Hatton wrote:
In the following code, the class B will not compile if the function da is
uncommented. I took exactly the same code, and turned it into templates.
Never used the template parameter in anything but the baseclass name in
the derived class, and the code compiles without any complaints about
protected
access. Why? What is different about the templated code?


The templated code is not really "compiled" unless you attempt to
instantiate the template. Did you? Where is the rest of the code?
Was there anything else? If there wasn't, then all the compiler did
for your templates was checking the syntax. Names were not resolved,
access rights weren't checked, etc.


Yes, but your question gave me an idea I hadn't tried. I hadn't actually
invoke any functions on the template. When I did, the compiler rejected it.

int main() {
BT<int> bt(5);
bt.da(1); // comment this out and it compiles
}

g++ -omain2 main2.cc
main2.cc: In member function `BT<T>& BT<T>::da(const int&) [with T = int]':
main2.cc:51: instantiated from here
main2.cc:30: error: `int AT<int>::x' is protected
main2.cc:40: error: within this context

--
STH
Hatton's Law: "There is only One inviolable Law"
KDevelop: http://www.kdevelop.org SuSE: http://www.suse.com
Mozilla: http://www.mozilla.org
Jul 22 '05 #7

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:92*************@newsread1.dllstx09.us.to.veri o.net...
Jonathan Turkanis wrote:

So is the dependent/non-dependent distinction a red herring here?


I am not sure I understand the question. Could you rephrase it?


Yes. I thought at first the reason access was not being checked was
that in the line

this->a.x += da_

the name a is qualified. But I see that Comeau compiles the code
wuthout the 'this->', as long as the template is not instantiated.

Jonathan
Jul 22 '05 #8

P: n/a
Steven T. Hatton wrote:
Victor Bazarov wrote:

Steven T. Hatton wrote:
In the following code, the class B will not compile if the function da is
uncommented. I took exactly the same code, and turned it into templates.
Never used the template parameter in anything but the baseclass name in
the derived class, and the code compiles without any complaints about
protected
access. Why? What is different about the templated code?


The templated code is not really "compiled" unless you attempt to
instantiate the template. Did you? Where is the rest of the code?
Was there anything else? If there wasn't, then all the compiler did
for your templates was checking the syntax. Names were not resolved,
access rights weren't checked, etc.

Yes, but your question gave me an idea I hadn't tried. I hadn't actually
invoke any functions on the template. When I did, the compiler rejected it.

int main() {
BT<int> bt(5);
bt.da(1); // comment this out and it compiles
}


Right. Instantiating a class template is not the same as instantiating
a member of a class template. If you don't call the function, it won't
be instantiated, and will not really be compiled (names resolved, access
checked, etc). So, to make sure a member of a template class is correct,
you got to try to use that member.

V
Jul 22 '05 #9

P: n/a
Jonathan Turkanis wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:92*************@newsread1.dllstx09.us.to.veri o.net...
Jonathan Turkanis wrote:


So is the dependent/non-dependent distinction a red herring here?


I am not sure I understand the question. Could you rephrase it?

Yes. I thought at first the reason access was not being checked was
that in the line

this->a.x += da_

the name a is qualified. But I see that Comeau compiles the code
wuthout the 'this->', as long as the template is not instantiated.


Aha. So, dependent/non-dependent distinction is not a red herring,
then, right?

V
Jul 22 '05 #10

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:ag*************@newsread1.dllstx09.us.to.veri o.net...
Jonathan Turkanis wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:92*************@newsread1.dllstx09.us.to.veri o.net...
Jonathan Turkanis wrote: So is the dependent/non-dependent distinction a red herring here?
Yes. I thought at first the reason access was not being checked was that in the line

this->a.x += da_

the name a is qualified. But I see that Comeau compiles the code
wuthout the 'this->', as long as the template is not instantiated.


Aha. So, dependent/non-dependent distinction is not a red herring,
then, right?


Comeau behaves the same with and without the qualification (which
makes sense, since I don't think the meaning of 'a' can change
depending on the template parameter T); that's why I said the
distinction was a red herring.

Jonathan
Jul 22 '05 #11

P: n/a
Jonathan Turkanis wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:ag*************@newsread1.dllstx09.us.to.veri o.net...
Jonathan Turkanis wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:92*************@newsread1.dllstx09.us.to.v erio.net...
Jonathan Turkanis wrote:
So is the dependent/non-dependent distinction a red herring here?
Yes. I thought at first the reason access was not being checked
was
that in the line

this->a.x += da_

the name a is qualified. But I see that Comeau compiles the code
wuthout the 'this->', as long as the template is not instantiated.


Aha. So, dependent/non-dependent distinction is not a red herring,
then, right?

Comeau behaves the same with and without the qualification (which
makes sense, since I don't think the meaning of 'a' can change
depending on the template parameter T); that's why I said the
distinction was a red herring.

OK, how about this:
--------------------------------
template<typename T>
class AT{
public:
AT(const int& x_=0): x(x_){}
protected:
int x;
};

template<typename T>
class BT: public AT<T>{
public:
BT(const int& x_=0): AT<T>(x_){}

BT& da(const int& da_)
{
a.x += da_;
return *this;
}

protected:
AT<T> a;
};

template<> class AT<int> {
public:
AT(int = 0) : x(0) {}
int x; /// Oops -- forgot 'protected'
};

int main() {
BT<double> btd;
btd.da(42); // error -- cannot access protected

BT<int> bti;
bti.da(42); // fine
}
------------------------------------------------
Jul 22 '05 #12

P: n/a

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:VS*************@newsread1.dllstx09.us.to.veri o.net...
Jonathan Turkanis wrote:
"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:ag*************@newsread1.dllstx09.us.to.veri o.net...
Jonathan Turkanis wrote:

"Victor Bazarov" <v.********@comAcast.net> wrote in message
news:92*************@newsread1.dllstx09.us.to.v erio.net...


>Jonathan Turkanis wrote:


>>So is the dependent/non-dependent distinction a red herring here?

Yes. I thought at first the reason access was not being checked


was
that in the line

this->a.x += da_

the name a is qualified. But I see that Comeau compiles the code
wuthout the 'this->', as long as the template is not

instantiated.
Aha. So, dependent/non-dependent distinction is not a red herring,then, right?

Comeau behaves the same with and without the qualification (which
makes sense, since I don't think the meaning of 'a' can change
depending on the template parameter T); that's why I said the
distinction was a red herring.

OK, how about this:
--------------------------------
template<typename T>
class AT{
public:
AT(const int& x_=0): x(x_){}
protected:
int x;
};

template<typename T>
class BT: public AT<T>{
public:
BT(const int& x_=0): AT<T>(x_){}

BT& da(const int& da_)
{
a.x += da_;
return *this;
}

protected:
AT<T> a;
};

template<> class AT<int> {
public:
AT(int = 0) : x(0) {}
int x; /// Oops -- forgot 'protected'
};

int main() {
BT<double> btd;
btd.da(42); // error -- cannot access protected

BT<int> bti;
bti.da(42); // fine
}
------------------------------------------------


Good. This shows why the access check has to be delayed, independent
of whether a is qualified.

Jonathan
Jul 22 '05 #13

This discussion thread is closed

Replies have been disabled for this discussion.