A mess with inheritance, virtual classes , and templates.
Hello all,
I have a code that works without templating and when I apply templates
doesn't.
I tried to simplify it as much as possible, but it is a little long.
This code works without templating:
//*****************************************************************
#include <iostream>
#include <cmath> // exp
using namespace std;
struct basf{
virtual double eval(void) const{ cerr << "ERROR: base
class()"<<endl; };
};
ostream& operator<<(ostream &os, const basf & bas){ os<< bas.eval();
return os; };
struct vfoo: public basf{
double * var;
vfoo( double * v, const string &rep1 ): var(v), rep(rep1){};
void operator=( const double & v ) { *var=v; };
// operator foo( ){ foo fun(this); return fun; };
// operator foo&( ){ foo fun(this); return fun; };
double eval() const{ return *var; };
};
struct foo{
basf *fp;
foo( basf * pbfun ) : fp(pbfun) { };
foo( vfoo &vx ) : fp(&vx) { };
// foo( ) { };
double eval(void) const{ return fp->eval(); };
};
struct efoo: public basf{
foo sub;
efoo( foo sf ) : sub(sf) {};
operator foo( ){ foo fun(this); return fun; };
double eval() const{ return exp( sub.eval() ); };
};
efoo exp3( foo sf ) { return efoo( sf ); };
void testfun2(void){
double x=14.10;
vfoo vx(&x,"x");
cout << "vx = " << vx << endl;
foo f1=vx;
cout <<" f1.eval() = "<< f1.eval() << endl;
foo f2= efoo(vx);
cout <<" f2.eval() = "<< f2.eval() << endl;
foo f3= exp3(f1);
cout <<" f3.eval() = "<< f3.eval() << endl;
}
int main( int argc, char** argv, char** envp){
testfun2();
return 0;
}
//*****************************************************************
But doesn't with templates:
//*****************************************************************
#include <iostream>
#include <cmath> // exp
using namespace std;
template <class T> struct basf{
virtual T eval(void) const{ cerr << "ERROR: base class()"<<endl; };
};
template<class T> ostream& operator<<(ostream &os, const basf<T> & bas)
{ os<< bas.eval(); return os; };
template <class T> struct vfoo: public basf<T>{
T * var;
vfoo( T * v, const string &rep1 ): var(v), rep(rep1){};
void operator=( const T & v ) { *var=v; };
// operator foo<T>( ){ foo<T> fun(this); return fun; };
// operator foo<T>&( ){ foo<T> fun(this); return fun; };
T eval() const{ return *var; };
};
template <class T> struct foo{
basf<T> *fp;
foo( basf<T> * pbfun ) : fp(pbfun) { };
foo( vfoo<T> &vx ) : fp(&vx) { };
// foo( ) { };
T eval(void) const{ return fp->eval(); };
};
template <class T> struct efoo: public basf<T>{
foo<T> sub;
efoo( foo<T> sf ) : sub(sf) {};
operator foo<T>( ){ foo<T> fun(this); return fun; };
T eval() const{ return exp( sub.eval() ); };
string str(void) const { return "exp("; };
};
template <class T> efoo<T> exp3( foo<T> sf ) { return
efoo<T>( sf ); };
void testfun2(void){
double x=14.10;
vfoo<double> vx(&x,"x");
cout << "vx = " << vx << endl;
foo<double> f1=vx;
cout <<" f1.eval() = "<< f1.eval() << endl;
foo<double> f2= efoo<double>(vx);
cout <<" f2.eval() = "<< f2.eval() << endl;
foo<double> f3= exp3(vx);
cout <<" f3.eval() = "<< f3.eval() << endl;
}
int main( int argc, char** argv, char** envp){
testfun2();
return 0;
}
//*****************************************************************
The error it gives (with gcc version 4.4.5) is
foo4.cpp: In function =91void testfun2()':
foo4.cpp:45: error: no matching function for call to
=91exp3(vfoo<double>&)'
The question is =BFWhy doesn't detect de conversion vfoo -> foo?, as you
see commented,
I tried to place vfoo after foo and doing the conversion in vfoo
instead of foo, but
that didn't work either.
=BFHow could I solve the problem? . My aim is to be able to write
exp3(vx) without having to do a cast or conversion in testfun2. I know
that I could write a overloaded function exp3
whose argument would be a vfoo, that I find that clumsy if I derive a
lot of classes from basf like vfoo.
Thanks in advance,
C=E9sar.