General -> www.parashift.com

All web addresses submitted for ratings

www.parashift.com

Postby sandodo » Thu Nov 13, 2014 9:40 am

The actual url I am bookmarking is http://www.parashift.com/c++-faq/ It contains all the useful solutions for frequent asked questions of c++ developers.
User avatar
sandodo
 
Rating: G
Total votes: 1462
Joined: Fri May 09, 2014 10:12 am

www.parashift.com

Postby xiongz » Thu Nov 13, 2014 10:21 am

I have benefited from answer at http://www.parashift.com/c++-faq/nondep ... mbers.html replated to template and inheritance. It saved my day.

Details as below:

[35.19] Why am I getting errors when my template-derived-class uses a member it inherits from its template-base-class?
Perhaps surprisingly, the following code is not valid C++, even though some compilers accept it:

template<typename T>
class B {
public:
void f() { } ← member of class B<T>
};

template<typename T>
class D : public B<T> {
public:
void g()
{
f(); ← bad (even though some compilers erroneously (temporarily?) accept it)
}
};
This might hurt your head; better if you sit down.
Within D<T>::g(), the name f does not depend on template parameter T, so f is known as a nondependent name. On the other hand, B<T> is dependent on template parameter T so B<T> is called a dependent name.

Here's the rule: the compiler does not look in dependent base classes (like B<T>) when looking up nondependent names (like f).

This doesn't mean that inheritance doesn't work. Class D<int> is still derived from class B<int>, the compiler still lets you implicitly do the is-a conversions (e.g., D<int>* to B<int>*), dynamic binding still works when virtual functions are invoked, etc. But there is an issue about how names are looked up.

Workarounds:

Change the call from f() to this->f(). Since this is always implicitly dependent in a template, this->f is dependent and the lookup is therefore deferred until the template is actually instantiated, at which point all base classes are considered.
Insert using B<T>::f; just prior to calling f().
Change the call from f() to B<T>::f(). Note however that this might not give you what you want if f() is virtual, since it inhibits the virtual dispatch mechanism.
User avatar
xiongz
 
Rating: G
Total votes: 92
Joined: Mon Jun 02, 2014 9:23 am


cron