Name Resolution for Class Derived from Template Argument

M

montyshasta

Take this code as a base case, it compiles successfully:

struct R
{
int i;
};
class S : public R
{
void F(void) {i = 0;}
};
S s;

Switch to deriving S from R as a template argument and the behavior
varies by compiler:

struct R
{
int i;
};
template <class T>
class S : public T
{
void F(void) {i = 0;}
};
S<R> s;

Visual Studio succeeds building this. GCC fails with "error: 'i'
was not declared in this scope". ICC (Intel's compiler) succeeds with
that instantiation but fails if you attempt an explicit template
instantiation, like:
template class S<R>;

GCC and ICC succeed if you switch to a qualified reference to i:
void F(void) {T::i = 0;}

Is the way namespaces are inherited from base classes supposed to work
differently if those base classes are template arguments or is
something wrong with the compilers?
 
O

Ondra Holub

(e-mail address removed) napsal:
Take this code as a base case, it compiles successfully:

struct R
{
int i;
};
class S : public R
{
void F(void) {i = 0;}
};
S s;

Switch to deriving S from R as a template argument and the behavior
varies by compiler:

struct R
{
int i;
};
template <class T>
class S : public T
{
void F(void) {i = 0;}
};
S<R> s;

Visual Studio succeeds building this. GCC fails with "error: 'i'
was not declared in this scope". ICC (Intel's compiler) succeeds with
that instantiation but fails if you attempt an explicit template
instantiation, like:
template class S<R>;

GCC and ICC succeed if you switch to a qualified reference to i:
void F(void) {T::i = 0;}

Is the way namespaces are inherited from base classes supposed to work
differently if those base classes are template arguments or is
something wrong with the compilers?

I think that behaviour of gcc is correct. When class is derived from
class defined by template parameter, you cannot access parent's members
with direct name, you have to write either T::member or this->member.
 
M

Marcus Kwok

Switch to deriving S from R as a template argument and the behavior
varies by compiler:

struct R
{
int i;
};
template <class T>
class S : public T
{
void F(void) {i = 0;}
};
S<R> s;

Visual Studio succeeds building this. GCC fails with "error: 'i'
was not declared in this scope". ICC (Intel's compiler) succeeds with
that instantiation but fails if you attempt an explicit template
instantiation, like:
template class S<R>;

GCC and ICC succeed if you switch to a qualified reference to i:
void F(void) {T::i = 0;}

Is the way namespaces are inherited from base classes supposed to work
differently if those base classes are template arguments or is
something wrong with the compilers?

See the FAQ (and the one following it too):
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top