What's wrong here? Accessing members of a templated base class

P

Pete

If anyone here can tell me what's going wrong in this snippet, I'd be much
obliged. It works under g++ 3.3 but not the (fussier) g++ 3.4. Thanks...



template<typename T>
struct base
{
T m_x;
};

template<typename T>
struct derived : public base<T>
{
void bleh();
};

template<typename T>
void derived<T>::bleh()
{
T b = base<T>::m_x; // OK
T a = m_x; // error: `m_x' undeclared
}

int main()
{
derived<int> c;
c.bleh();
}
 
J

John Harrison

Pete said:
If anyone here can tell me what's going wrong in this snippet, I'd be much
obliged. It works under g++ 3.3 but not the (fussier) g++ 3.4. Thanks...



template<typename T>
struct base
{
T m_x;
};

template<typename T>
struct derived : public base<T>
{
void bleh();
};

template<typename T>
void derived<T>::bleh()
{
T b = base<T>::m_x; // OK
T a = m_x; // error: `m_x' undeclared
}

It's because 3.4 implements two phase look up correctly and therefore does
not examine the base class when looking up a unqualified dependent name.

Either base<T>::m_x or this->m_x will fix the problem.

John
 
R

Rob Williscroft

Pete wrote in in
comp.lang.c++:
If anyone here can tell me what's going wrong in this snippet, I'd be
much obliged. It works under g++ 3.3 but not the (fussier) g++ 3.4.
Thanks...

The name m_x from the base 'base< T >' is dependant on the template
argument 'T', you need to tell a conforming compiler (g++ 3.4 in this
case) that 'm_x' is in 'base said:
template<typename T>
struct base
{
T m_x;
};

template<typename T>
struct derived : public base<T>
{

Fix 1:

using base said:
void bleh();
};

template<typename T>
void derived<T>::bleh()
{

Fix 2:
T b = base<T>::m_x; // OK
T a = m_x; // error: `m_x' undeclared

Fix 3:

T c = this->m_x;

Note that Fix 1 puts a requirement on derived< T > that the
instansiated specialization for 'base< T >' contains a non-type
member m_x, Fix 2 and 3 only make this requirement if
derived< T >::bleh() is instantiated.

HTH.

Rob.
 
S

Sharad Kala

Pete said:
If anyone here can tell me what's going wrong in this snippet, I'd be much
obliged. It works under g++ 3.3 but not the (fussier) g++ 3.4. Thanks...



template<typename T>
struct base
{
T m_x;
};

template<typename T>
struct derived : public base<T>
{
void bleh();
};

template<typename T>
void derived<T>::bleh()
{
T b = base<T>::m_x; // OK
T a = m_x; // error: `m_x' undeclared
}

int main()
{
derived<int> c;
c.bleh();
}

That's two phase name lookup. I just checked our FAQ and saw that it is
actually mentioned there.
http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.1
7
If you want to know even better then read Part II (Chapters 9 and 10) of C++
Templates (Josuttis/Vandevoorde). They explain it quite well in their book.

-Sharad
 
P

Pete

Sharad said:
That's two phase name lookup. I just checked our FAQ and saw that it is
actually mentioned there.
http://www.parashift.com/c++-faq-lite/containers-and-templates.html#faq-34.1
7
If you want to know even better then read Part II (Chapters 9 and 10) of
C++ Templates (Josuttis/Vandevoorde). They explain it quite well in their
book.

Ah, the c++-faq. Nice explanation... quite an eye-opener. I'll have to
change a load of code because of that one. Bah.

Thanks for the help, everyone.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top