ElDesdichado | Aprés avoir lu une réponse de JoelF sur friend (il aime pas, moi non plus), je me suis dit que je pourrai peut-être éliminer définitivement mes opérateurs friend dans mon moteur de calcul (j'avais utilisé le Barton-Nackman trick, mais c'est peut-être inutile), donc voilà le problème, je veux créer des opérateurs sur des pointers qui pointent sur des objets différent mais ayant en commun un Functor sur lequel je veux opérer, le pire c'est que les objets sont templates, donc on a :
Code :
- class EQPDEProperty_Base{...};
|
Je définis une class SingleOperator pour mes Operator agissant sur un seul pointer (de classe X) me retournant un pointer (sur R):
Code :
- template<int INDEX_PDE, class X, class R>
- class EQSingleOperator : virtual public R, public with_type_traits<EQSingleOperator<INDEX_PDE,X,R> >
- {
- public:
- using with_type_traits<EQSingleOperator<INDEX_PDE,X,R> >::sp;
- using with_type_traits<EQSingleOperator<INDEX_PDE,X,R> >::const_sp;
- typedef boost::function<double(double,double,double,AuxValues::sp,int)> Function;
- EQSingleOperator(){}
- EQSingleOperator(std::string sOperator, typename X::sp spX) : m_sOperator(sOperator), m_spX(spX), m_isPointer(true)
- {
- setStartDate(m_spX->getStartDate());
- setEndDate(m_spX->getEndDate());
- setType("("+m_sOperator+m_spX->getType()+" )" );
- setPoints(m_spX->getPoints());
- m_Evaluation = spX->get_functor();
- }
- virtual ~EQSingleOperator()
- {};
- typename X::sp getVar()
- {
- return m_spX;
- }
- std::string getOperator() {return m_sOperator;}
- void setOperator(std::string sOperator) {m_sOperator=sOperator;}
- void updateType()
- {
- setType("("+m_sOperator+m_spX->getType()+" )" );
- }
- inline Function getEvaluation(){return m_Evaluation;}
- private:
- std::string m_sOperator;
- typename X::sp m_spX;
- Function m_Evaluation;
- };
|
Bon ensuite je fais une classe pour la multiplication par un double:
Code :
- template<int INDEX_PDE, class X, class R>
- class EQScalarMultProperty : virtual public EQSingleOperator<INDEX_PDE,X,R>, public with_type_traits<EQScalarMultProperty<INDEX_PDE,X,R> >
- {
- public:
- using with_type_traits<EQScalarMultProperty<INDEX_PDE,X,R> >::sp;
- using with_type_traits<EQScalarMultProperty<INDEX_PDE,X,R> >::const_sp;
- EQScalarMultProperty(double dLambda,typename X::sp spX) : EQSingleOperator<INDEX_PDE,X,R>("",spX)
- {
- std::stringstream s;
- s<<dLambda;
- std::string sLambda = s.str();
- std::string sOperator = sLambda;
- sOperator += "*";
- m_dLambda = dLambda;
- setOperator(sOperator);
- updateType();
- }
- virtual ~EQScalarMultProperty()
- {};
- virtual double evaluate(double dTime, double dPoint, double dValue, AuxValues::sp spAuxValues, int id)
- {
- Function eval = getEvaluation();
- return eval(dTime,dPoint,dValue,spAuxValues,id)*m_dLambda;
- }
- virtual boost::function<double(double,double,double,AuxValues::sp,int)> get_functor()
- {
- return boost::function<double(double,double,double,AuxValues::sp,int)>(boost::bind(evaluate,(*this),_1,_2,_3,_4,_5));
- }
- private:
- double m_dLambda;
- };
|
Et ensuite je reprend la classe de base EQPDEPricerProperty_Base pour définir l'opérateur suivant:
Code :
- friend sp operator*(double dLambda,sp spP)
- {
- EQScalarMultProperty<-1000,EQPDEProperty_Base,EQPDEProperty_Base>::sp
- spProperty(new EQScalarMultProperty<-1000,EQPDEProperty_Base,EQPDEProperty_Base>(dLambda,spP));
- return spProperty;
- }
- friend sp operator*(sp spP,double dLambda)
- {
- EQScalarMultProperty<-1000,EQPDEProperty_Base,EQPDEProperty_Base>::sp
- spProperty(new EQScalarMultProperty<-1000,EQPDEProperty_Base,EQPDEProperty_Base>(dLambda,spP));
- return spProperty;
- }
|
Bien entendu si j'enlève le friend j'ai une belle erreur de compilation:
d:\HLML2\EQUITY\EQ\BSCHModelEQ\PDEPricerProperties.hpp(912) : error C2804: binary 'operator *' has too many parameters
d:\HLML2\EQUITY\EQ\BSCHModelEQ\PDEPricerProperties.hpp(912) : error C2333: 'EQPDEProperty_Base::operator`*'' : error in function declaration; skipping function body
Bon alors il y a toujours la solution de me dire que je fais n'importequoi (en fait c'est une possibilité tout à fait crédible), m'enfin l'idée c'est d'avoir des modules qui représente des produits financiers et de les combiner pour faire des produits structurés (sauf qu'en fait c'est un peu comme additioner des choux et des carottes) et qu'à la fin je veux faire de l'algèbre avec des pointeurs style:
Code :
- spResult = 2*(spCall+1)-spSwap+spCall2*spCall3;
|
Donc en fait là ca marche mais je suis loin d'être sûr que ce soit bien fait. En plus comme je suis un gros malade, je fais aussi fonctionner mes classe d'opérateurs directement sur les objets genre je veux faire des trucs du style:
Code :
- Result = 2*(Call+1)-Swap+Call2*Call3;
|
|