Templates: Why does this fail to compile?

A

A Moore

///
/// Both g++ 3.4.1 and comeau 4.3.3 report "i undefined"
///
#include <iostream>

template<typename T>
class Base
{
protected:
int i;
};


template<typename T>
class Derived : public Base< T >
{
public:
void f() {
i = 0;
std::cout << i << std::endl;
}
};


int main()
{
Derived< int > d;
d.f();
return 0;
}
 
A

Alf P. Steinbach

* A Moore:
///
/// Both g++ 3.4.1 and comeau 4.3.3 report "i undefined"
///
#include <iostream>

template<typename T>
class Base
{
protected:
int i;
};


template<typename T>
class Derived : public Base< T >
{
public:
void f() {
i = 0;
std::cout << i << std::endl;
}
};

Here 'i' could conceivably refer to a global variable.

Preferred solution: 'using Base<T>::i;'.

Alternative solution: 'this->i'.
 
A

Andrey Tarasevich

A said:
#include <iostream>

template<typename T>
class Base
{
protected:
int i;
};


template<typename T>
class Derived : public Base< T >
{
public:
void f() {
i = 0;

In this context non-qualified name 'i' is not a dependent name.
Non-dependent names are looked up immediately in accordance with usual
look-up rules, except that dependent base classes are excluded from this
process. That's why 'i' is not found and the code fails to compile. If
declare an 'i' variable at namespace scope, the code will compile, but
that 'i' will refer to the namespace variable, not to the base class member.

If you want your 'i' to refer to the 'i' in the base class, you have to
explicitly turn it into a dependent name. This can be done by either using

this->i = 0;

or by using a qualified name
 
A

Andrey Tarasevich

A said:
...
Well this->i does not seem very dependent to me...
How come?
...

'Base<T>' is a dependent type for obvious reasons.

'Derived' is a dependent type in accordance with 14.6.2.1/1 - it is a
compound type constructed from a dependent type ('Base<T>').

'this' is a type-dependent expression in accordance with 14.6.2.2/2 -
class type of the enclosing member function ('Derived') is dependent.

'this->i' is a type-dependent expression in accordance with 14.6.2.2/3 -
its subexpression ('this') is type-dependent.
 
S

Sumit Rajan

A Moore said:
///
/// Both g++ 3.4.1 and comeau 4.3.3 report "i undefined"
///
#include <iostream>

template<typename T>
class Base
{
protected:
int i;
};


template<typename T>
class Derived : public Base< T >
{
public:
void f() {
i = 0;
std::cout << i << std::endl;
}
};


int main()
{
Derived< int > d;
d.f();
return 0;
}

Try the FAQ:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

(And the next question as well)

Regards,
Sumit.
 
A

A Moore

Thank you! This was very informative and impressive.

The issue looks very unnatural to me, but then
again I am not well versed in the standard.
 
A

A Moore

Thanks for your help!
* A Moore:



Here 'i' could conceivably refer to a global variable.

Preferred solution: 'using Base<T>::i;'.

Alternative solution: 'this->i'.
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top