Re: Defining a cast on a templated class
On Nov 15, 5:32 am, Michael DOUBEZ <michael.dou...@free.fr> wrote:
//implement here detail of body composite
namespace imp
{
//interface of cell body
template<class T>
struct cell_body
{
virtual ~cell_body(){}
virtual T get_value()const=0;
};
tyedef boost::shared_ptr<cell_body> cell_body_ptr;
//counted cell body storing value
template<class T>
struct cell_body_value: public cell_body
{
cell_body_value(const T& t=T()):t_(t){}
T get_value()const{return t_;}
private:
T t_;
};
//cell body of lazy evaluation of binary operator
template<class T,class BinaryOperator>
struct cell_body_op: public cell_body
{
cell_body_op( cell_body_ptr lhs,
cell_body_ptr rhs,
const BinaryOperator& op=BinaryOperator()):
lhs_(lhs),
rhs_(rhs),
op_(op){}
virtual T get_value(){return op(lhs->get_value(),rhs->get_value();}
private:
cell_body_ptr lhs_;
cell_body_ptr rhs_;
BinaryOperator op_;
};
//do the same for unary operator, ...
};
template<class T>
class cell
{
public:
//ensure get_value() always work
cell<T>(const T& t=T())
{
value_=new imp::cell_body_value(t);
}
//make a const version to use when rhs is local
cell<T>& operator+=(const cell<T>& c)
{
value_=new imp::cell_body_op(value_,c.value_,std::plus());
}
inline T get_value()const{ return value_->get_value();}
private:
imp::cell_body_ptr value_;
};
The code is not tested but should be close.
It didn't compile but I tried hacking through it to make it compile.
I've managed to make it compile but now it won't run ^^;
Here's what I hacked up:
//I removed the namespace imp thing for now, since
//I was getting rather confused at some point
//implement here detail of body composite
//interface of cell body
template<class T>
class cell_body
{
public:
virtual ~cell_body(){}
virtual T get_value()const{return T();};
};
//The compiler rejected the typedef (because the
//cell_body didn't have a template instantiation)
//so I removed it and instantiated the typedef in
//the classes.
//counted cell body storing value
template<class T>
class cell_body_value: public cell_body<T>
{
public:
cell_body_value(const T& t=T()):t_(t){}
T get_value()const{return t_;}
private:
T t_;
};
//cell body of lazy evaluation of binary operator
template<class T,class BinaryOperator>
class cell_body_op: public cell_body<T> //Added the <T>
{
typedef boost::shared_ptr<cell_body<T> > cell_body_ptr; //Added the
<T>
public:
cell_body_op( cell_body_ptr lhs,
cell_body_ptr rhs,
const BinaryOperator& op=BinaryOperator()):
lhs_(lhs),
rhs_(rhs),
op_(op){}
//minor typos (missing const and _)
virtual T get_value() const {return op_(lhs_->get_value(),rhs_-
get_value());}
private:
cell_body_ptr lhs_;
cell_body_ptr rhs_;
BinaryOperator op_;
};
template<class T>
class cell
{
//instantiated the typedef again.
typedef boost::shared_ptr<cell_body<T> > cell_body_ptr;
public:
//ensure get_value() always work
cell<T>(const T& t=T())
{
//The compiler rejected the direct assignment to value_
//so I did this.
cell_body_ptr tmp(new cell_body_value<T>(t)); //Added the
<T>
value_=tmp;
}
//make a const version to use when rhs is local
//I think this is the function that crashes
cell<T>& operator+=(const cell<T>& c)
{
//The compiler rejected the direct assignment to value_
cell_body_ptr tmp(new cell_body_op<T, std::plus<T>
(value_, c.value_, std::plus<T>()));
value_=tmp;
}
inline T get_value()const{ return value_->get_value();}
private:
cell_body_ptr value_;
};
I retained the old operator+ definitions.
This works:
cell<int> v;
v = 1;
cout << v.get_value();
This crashes:
cell<int> v, v2;
v = v2 + 1;
cout << v.get_value();
This leads me to suspect that I did something very wrong in the +=
code, possibly in using std::plus<T> in the template instantiation