Weird compile error in conjunction with templates & inheritance

S

Student

Why is the following code, which used to compile fine some years ago,
not compiling anymore? :)

g++ test.cpp
test.cpp: In member function ‘int D<T>::Size()’:
test.cpp:35: error: ‘v’ was not declared in this scope
test.cpp:35: error: ‘k’ was not declared in this scope


// test.cpp

template <typename T = int>
class B
{
public:
int v, k;

B(int Av, int Ak)
{
v = Av;
k = Ak;
}

virtual int Size() = 0;

//...
};

template <typename T = int>
class D : public B<T>
{
public:
D(int Av, int Ak) : B<T>(Av, Ak)
{
}

int Size()
{
return v * k;
}
};

int main(int argc, char* argv[])
{
D<long> C(10, 2);
//...
return 0;
}
 
S

Student

[REPOST]

Why is the following code, which used to compile fine some years ago,
not compiling anymore? :)

g++ test.cpp
test.cpp: In member function ‘int D<T>::Size()’:
test.cpp:35: error: ‘v’ was not declared in this scope
test.cpp:35: error: ‘k’ was not declared in this scope


// test.cpp

template <typename T = int>
class B
{
public:
int v, k;

B(int Av, int Ak)
{
v = Av;
k = Ak;
}

virtual int Size() = 0;

//...
};


template <typename T = int>
class D : public B<T>
{
public:
D(int Av, int Ak) : B<T>(Av, Ak)
{
}

int Size()
{
return v * k;
}
};


int main(int argc, char* argv[])
{
D<long> C(10, 2);
//...
return 0;
}
 
S

Student

The base class depends on the template argument and can be different in
different specializations, so the compiler cannot be sure what v and k
really represent. Clarify with:

return this->v * this->k;


hth
Paavo

Hey, cool, thanks, this solves the problem,
although I'm not really convinced why one has to use "this" there.
 
S

Student

Hey, cool, thanks, this solves the problem,
although I'm not really convinced why one has to use "this" there.

Hmm... it's a nightmare to change all the code.
I think this is clearly a compiler bug.
 
M

Marcel Müller

Hi,

Paavo said:
Also, it seems you are trying to mix templates with OOP and
virtual methods, this is not a very good design as they both solve
similar problems, but in different ways which may easily conflict each
other.

why do you think that these concepts should be used mutually exclusive?

I use templates to support interface implementations from time to time.
This will obviously mix virtual methods and templates.


Marcel
 
S

Student

No, it's not a bug, it's a feature ;-) Do not expect this to go away.

Normally there are not so many templated base classes used in the code,
why do you think you have to change "all the code"? Normally all member
variables are private, so you would not use them in derived classes
anyway. Also, it seems you are trying to mix templates with OOP and
virtual methods, this is not a very good design as they both solve
similar problems, but in different ways which may easily conflict each
other. At least be prepared to having some complicated and cumbersome
code if you insist on using them together.

Since this code compiled fine some years ago,
does anybody know if there is a compiler switch in g++
to get the code compile again without the above ugly "this->" 'workaround'?

g++ --version
g++ (Debian 4.4.4-11) 4.4.5 20100824 (prerelease)
 
M

Marc

Student said:
Since this code compiled fine some years ago,
does anybody know if there is a compiler switch in g++
to get the code compile again without the above ugly "this->" 'workaround'?

Not that I know of. Is the solution of using "using" also too ugly for you?
 
S

Student

Not that I know of. Is the solution of using "using" also too ugly for you?

To be honest: yes.
Because in the math formulae I use there's of course no such thing
as "this->", so then why should I cripple the code with it?
For me, the use of "this->" makes no sense at all.
 
Ö

Öö Tiib

To be honest: yes.
Because in the math formulae I use there's of course no such thing
as "this->", so then why should I cripple the code with it?
For me, the use of "this->" makes no sense at all.

You perhaps did not understand the question there. It was what is ugly
about that solution:


// test.cpp
template <typename T = int>
class B
{
public:
int v, k;
B( int Av, int Ak )
: v( Av )
, k( Ak )
{}
virtual int Size() = 0;
//...
};

template <typename T = int>
class D : public B<T>
{
public:
using B<T>::v;
using B<T>::k;
D( int Av, int Ak )
: B<T>( Av, Ak )
{}
int Size()
{
return v * k;
}
};

int main(int argc, char* argv[])
{
D<long> C(10, 2);
//...
return 0;
}
 
S

Student

You perhaps did not understand the question there. It was what is ugly
about that solution:

Acually I knew exactly what he meant
(ie. this: http://www.parashift.com/c++-faq-lite/templates.html#faq-35.19 ),
but when replying I still was too much fixated on the "this->" thing,
so I forgot the "using"... :)

Ok, your example makes it clear, this one is maybe a better
workaround than the "this->" method. But I still think such
a workaround is not really neccessary (I mean it shouldn't be).
// test.cpp
template<typename T = int>
class B
{
public:
int v, k;
B( int Av, int Ak )
: v( Av )
, k( Ak )
{}
virtual int Size() = 0;
//...
};

template<typename T = int>
class D : public B<T>
{
public:
using B<T>::v;
using B<T>::k;
D( int Av, int Ak )
: B<T>( Av, Ak )
{}
int Size()
{
return v * k;
}
};

int main(int argc, char* argv[])
{
D<long> C(10, 2);
//...
return 0;
}
 
J

James Kanze

No, it's not a bug, it's a feature ;-) Do not expect this to go away.

Not a compiler bug, but arguably a bug in the standard.
Normally there are not so many templated base classes used in the code,
why do you think you have to change "all the code"? Normally all member
variables are private, so you would not use them in derived classes
anyway. Also, it seems you are trying to mix templates with OOP and
virtual methods, this is not a very good design as they both solve
similar problems, but in different ways which may easily conflict each
other.

I can't follow you there. Templates and virtual functions are
radically different: templates provide common implementation for
different types; virtual functions provide different
implementations for common types.
At least be prepared to having some complicated and cumbersome
code if you insist on using them together.

Not at all. The mix together very well. What creates
complicated and cumbersome code is trying to use only one (which
results in using one in cases where the other is more
appropriate).
 

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,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top