Virtual functions in template class issue

  • Thread starter Thread starter Chris
  • Start date Start date
C

Chris

I am having a very strange problem involving virtual
functions in template classes. First of all, here is an
extremely simplified structure of the two classes I am
having problems with.

template<class Type> class base
{
public:
base& operator/=(const base&);
Type *image;
// There is more stuff here, but it is not necessary
for this problem
}

class derived : public base<complex<double> >
{
// There is stuff here, but it is not necessary for
this problem
}

template<class Type> base& base<Type>::operator/=(const
base& im)
{
for(int i=0; i<loopLength; i++)
{
if(im.image != 0) {
image = image / im.image; }
else {
image = 0; }
}
return *this;
}

Now as that stands everything works fine, as it should.
The problem comes when I try to make the operator/
function a virtual function in base. I want to derive
another class from base that needs a different
implementation of the operator, but derived can use the
same implementation. So, the only change I made to the
code is:

template<class Type> class base
{
public:
virtual base& operator/=(const base&);
Type *image;
// There is more stuff here, but it is not necessary
for this problem
}

It seems to me that this should all still work, but
instead I get 23 strange errors when I try to compile the
code with the virtual function. I should point out that
base and derived are in separate files and these errors
appear when the source for derived compiles. I don't
understand why I get these errors at all. They all come
from the line of code that contains the if(im.image !=
0). I actually have other operators that get the same
errors. They all come from comparisons in if statements
such as if(im.image != image) and they are all
nearly identical except for the operator they list.

I am completely baffled so please help me. Why does it
work completely fine without the virtual?

Chris



The 23 Errors
-----------------------------------------

Image.cpp(500): error C2784: 'bool std::operator !=(const
_Ty &,const std::complex<_Ty> &)' : could not deduce
template argument for 'const std::complex<_Ty> &'
from 'int'

Image.cpp(500): error C2782: 'bool std::operator !=(const
std::complex<_Ty> &,const _Ty &)' : template
parameter '_Ty' is ambiguous

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::complex<_Ty> &,const std::complex<_Ty> &)' : could
not deduce template argument for 'const std::complex<_Ty>
&' from 'int'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem
*)' : could not deduce template argument for 'const
std::basic_string<_Elem,_Traits,_Ax> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem
*)' : could not deduce template argument for 'const
std::basic_string<_Elem,_Traits,_Ax> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem
*)' : could not deduce template argument for 'const
std::basic_string<_Elem,_Traits,_Ax> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
_Elem *,const std::basic_string<_Elem,_Traits,_Alloc>
&)' : could not deduce template argument for 'const T1 *'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::basic_string<_Elem,_Traits,_Alloc> &,const
std::basic_string<_Elem,_Traits,_Alloc> &)' : could not
deduce template argument for 'const
std::basic_string<_Elem,_Traits,_Ax> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::basic_string<_Elem,_Traits,_Alloc> &,const
std::basic_string<_Elem,_Traits,_Alloc> &)' : could not
deduce template argument for 'const
std::basic_string<_Elem,_Traits,_Ax> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::basic_string<_Elem,_Traits,_Alloc> &,const
std::basic_string<_Elem,_Traits,_Alloc> &)' : could not
deduce template argument for 'const
std::basic_string<_Elem,_Traits,_Ax> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::allocator<_Ty> &,const std::allocator<_Other> &)' :
could not deduce template argument for 'const
std::allocator<_Ty> &' from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::allocator<_Ty> &,const std::allocator<_Other> &)' :
could not deduce template argument for 'const
std::allocator<_Ty> &' from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::allocator<_Ty> &,const std::allocator<_Other> &)' :
could not deduce template argument for 'const
std::allocator<_Ty> &' from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::istreambuf_iterator<_Elem,_Traits> &,const
std::istreambuf_iterator<_Elem,_Traits> &)' : could not
deduce template argument for 'const
std::istreambuf_iterator<_Elem,_Traits> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::istreambuf_iterator<_Elem,_Traits> &,const
std::istreambuf_iterator<_Elem,_Traits> &)' : could not
deduce template argument for 'const
std::istreambuf_iterator<_Elem,_Traits> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::istreambuf_iterator<_Elem,_Traits> &,const
std::istreambuf_iterator<_Elem,_Traits> &)' : could not
deduce template argument for 'const
std::istreambuf_iterator<_Elem,_Traits> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::reverse_iterator<_RanIt> &,const
std::reverse_iterator<_RanIt> &)' : could not deduce
template argument for 'const
std::reverse_iterator<_RanIt> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::reverse_iterator<_RanIt> &,const
std::reverse_iterator<_RanIt> &)' : could not deduce
template argument for 'const
std::reverse_iterator<_RanIt> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::reverse_iterator<_RanIt> &,const
std::reverse_iterator<_RanIt> &)' : could not deduce
template argument for 'const
std::reverse_iterator<_RanIt> &'
from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' :
could not deduce template argument for 'const
std::pair<_Ty1,_Ty2> &' from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' :
could not deduce template argument for 'const
std::pair<_Ty1,_Ty2> &' from 'std::complex<double>'

Image.cpp(500): error C2784: 'bool std::operator !=(const
std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' :
could not deduce template argument for 'const
std::pair<_Ty1,_Ty2> &' from 'std::complex<double>'

Image.cpp(500): error C2676: binary '!
=' : 'std::complex<double>' does not define this operator
or a conversion to a type acceptable to the predefined
operator
 
Chris said:
I am having a very strange problem involving virtual
functions in template classes. First of all, here is an
extremely simplified structure of the two classes I am
having problems with.

template<class Type> class base
{
public:
base& operator/=(const base&);
Type *image;
// There is more stuff here, but it is not necessary
for this problem
}

I guess that in the real code, all the classes are terminated by a
semicolon. :-)
class derived : public base<complex<double> >
{
// There is stuff here, but it is not necessary for
this problem
}

template<class Type> base& base<Type>::operator/=(const

I think the return value should be

base said:
base& im)
{
for(int i=0; i<loopLength; i++)
{
if(im.image != 0) {


And here is your missing operator!=(), since the complex types cannot
be compared to int. Change it to 0.0 and it will compile.
image = image / im.image; }
else {
image = 0; }
}
return *this;
}




Bo Persson
(e-mail address removed)
 
Also addressed in vc.language and vc.stl.

Please don't multipost. If you must post the same message to multiple
groups, you should crosspost.
 
Chris said:
I am having a very strange problem involving virtual
functions in template classes. First of all, here is an
extremely simplified structure of the two classes I am
having problems with.

template<class Type> class base
{
public:
base& operator/=(const base&);
Type *image;
// There is more stuff here, but it is not necessary
for this problem
}

class derived : public base<complex<double> >
{
// There is stuff here, but it is not necessary for
this problem
}

template<class Type> base& base<Type>::operator/=(const
base& im)

This needs to be:
template<class Type> base<Type>& base<Type>::operator/=(const
base said:
{
for(int i=0; i<loopLength; i++)
{
if(im.image != 0) {


Your use of literal 0 here should be Type(0). As it stands, the
compiler needs to do 2 conversions to turn 0 into a
std::complex<double>. First, 0 (an int) needs to be converted to a
double, then the double needs to be converted to a complex<double>.
The compiler won't do 2 conversions, so you need to help it out with
one.
image = image / im.image; }
else {
image = 0; }
}
return *this;
}

[snip]


It seems to me that this should all still work, but
instead I get 23 strange errors when I try to compile the
code with the virtual function. I should point out that


The 23 errors come from the fact that there are 23 operator!=()s in
scope and it's trying all of them looking for a match.

[snip]
I am completely baffled so please help me. Why does it
work completely fine without the virtual?

virtual is a red-herring here. If you eliminate the derived class and
make operator/= non-virtual, the follow will still produce the 23
errors:

int main() {
base<std::complex<double> > x;
x /= x;
}

"x /= x" is needed to force the instantiation of base<T>::operator/=,
where the real problem is. Using virtual also forces that
instantiation so that the compiler can generate the vtables for base
and derived.

Hope this helps,

John
 
Back
Top