By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,412 Members | 1,006 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,412 IT Pros & Developers. It's quick & easy.

Virtual functions in template class issue

P: n/a
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[i] != 0) {
image[i] = image[i] / im.image[i]; }
else {
image[i] = 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[i] !=
0). I actually have other operators that get the same
errors. They all come from comparisons in if statements
such as if(im.image[i] != image[i]) 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

Nov 16 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a

"Chris" <ch******@ufl.edu> skrev i meddelandet
news:04****************************@phx.gbl...
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<Type>&
base& im)
{
for(int i=0; i<loopLength; i++)
{
if(im.image[i] != 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[i] = image[i] / im.image[i]; }
else {
image[i] = 0; }
}
return *this;
}


Bo Persson
bo**@telia.com

Nov 16 '05 #2

P: n/a
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.

--
Craig Powers
MVP - Visual C++
Nov 16 '05 #3

P: n/a
"Chris" <ch******@ufl.edu> wrote in message news:<04****************************@phx.gbl>...
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<Type>& im)
{
for(int i=0; i<loopLength; i++)
{
if(im.image[i] != 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[i] = image[i] / im.image[i]; }
else {
image[i] = 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
Nov 16 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.