Happy Monday all,
When trying to use the quantlib Handle<.>, I got a compiler error: >c:\work\quantlib\quantlib-1.0.1\ql\handle.hpp(143) : error C2664: 'QuantLib::Observer::unregisterWith' : cannot convert parameter 1 from 'boost::shared_ptr<T>' to 'const boost::shared_ptr<T> &' Though I haven't changed anything in handle.hpp. Here's the code that generates the error: class Foo { public: Integer i; Foo() { i = 0; } }; int main() { Handle<Foo> c ( boost::shared_ptr<Foo>(new Foo())); return 0; } Any ideas what's the cause or solution? Thanks Philip ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
The shared pointer is a temporary variable. Create it in the main then create a handle using it (you should never create a shared pointer in a function call anyway).
Sent from my BlackBerry® wireless device -----Original Message----- From: P Nelnik <[hidden email]> Date: Mon, 24 May 2010 13:35:40 To: <[hidden email]> Subject: [Quantlib-users] quantlib Handle compile error ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
In reply to this post by P Nelnik
The problem is the temporary. C++ doesn't allow binding a temporary to a non-const reference.
Simon Courtenage On Mon, May 24, 2010 at 6:35 AM, P Nelnik <[hidden email]> wrote: Happy Monday all, -- ------------------------------------------------------------------------ Simon Courtenage | simoncourtenage.wordpress.com Twitter: simoncourtenage | Skype: simon99ctg Facebook: Simon Courtenage | IM: [hidden email] ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
In reply to this post by P Nelnik
On Mon, 2010-05-24 at 13:35 +0800, P Nelnik wrote:
> When trying to use the quantlib Handle<.>, I got a compiler error: > > >c:\work\quantlib\quantlib-1.0.1\ql\handle.hpp(143) : error C2664: > 'QuantLib::Observer::unregisterWith' : cannot convert parameter 1 from > 'boost::shared_ptr<T>' to 'const boost::shared_ptr<T> &' The implementation of Handle<T> requires T to inherit from Observable. Luigi -- Glendower: I can call spirits from the vasty deep. Hotspur: Why, so can I, or so can any man; But will they come when you do call for them? -- King Henry the Fourth Part I, Act III, Scene I ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Thanks Luigi and Simons (I & II) for your responses.
A couple of suggestion: 1: perhaps we should change the code in Examples/EquityOption/EquityOption.cpp: Handle<YieldTermStructure> flatTermStructure( boost::shared_ptr<YieldTermStructure>( new FlatForward(settlementDate, riskFreeRate, dayCounter))); since it may leak memory and it sets a bad example. 2: When a developer tries to implement Handle<T> where T doesn't derive from Observable, he's told there is an error in: inline void Handle<T>::Link::linkTo(const boost::shared_ptr<T>& h, bool registerAsObserver) { A one line comment in that could warning developers that T must derive from Observable Cheers Philip On Mon, May 24, 2010 at 2:52 PM, Luigi Ballabio <[hidden email]> wrote:
------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
On Mon, 2010-05-24 at 15:30 +0800, P Nelnik wrote:
> Thanks Luigi and Simons (I & II) for your responses. > > A couple of suggestion: > 1: perhaps we should change the code in > Examples/EquityOption/EquityOption.cpp: > > Handle<YieldTermStructure> flatTermStructure( > boost::shared_ptr<YieldTermStructure>( > new FlatForward(settlementDate, riskFreeRate, > dayCounter))); > since it may leak memory and it sets a bad example. Where can it leak memory? > 2: When a developer tries to implement Handle<T> where T doesn't > derive from Observable, > he's told there is an error in: > inline void Handle<T>::Link::linkTo(const > boost::shared_ptr<T>& h, bool registerAsObserver) { > A one line comment in that could warning developers that T must > derive from Observable It's already in the documentation for Handle (the docs before the class definition.) Luigi -- Zawinski's Law: Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can. ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
In reply to this post by P Nelnik
On the first point, it is a good idea not to use shared_ptr temporaries in function calls - this page http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/shared_ptr.htm explain why (see the section on "Best Practices") - the memory leak would only really occur where there are two or more arguments and the evaluation of one arg could potentially lead to an exception being thrown, but it's still a good idea to avoid this coding practice.
Simon Courtenage On Mon, May 24, 2010 at 8:30 AM, P Nelnik <[hidden email]> wrote: Thanks Luigi and Simons (I & II) for your responses. -- ------------------------------------------------------------------------ Simon Courtenage | simoncourtenage.wordpress.com Twitter: simoncourtenage | Skype: simon99ctg Facebook: Simon Courtenage | IM: [hidden email] ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
In reply to this post by Luigi Ballabio
Sorry for asking what might be a silly question but if, in Handle<T>,
T must inherit from Observable, why is Handle a template class? Thanks Simon Courtenage On 24 May 2010, at 09:19, Luigi Ballabio <[hidden email]> wrote: > On Mon, 2010-05-24 at 15:30 +0800, P Nelnik wrote: >> Thanks Luigi and Simons (I & II) for your responses. >> >> A couple of suggestion: >> 1: perhaps we should change the code in >> Examples/EquityOption/EquityOption.cpp: >> >> Handle<YieldTermStructure> flatTermStructure( >> boost::shared_ptr<YieldTermStructure>( >> new FlatForward(settlementDate, riskFreeRate, >> dayCounter))); >> since it may leak memory and it sets a bad example. > > Where can it leak memory? > >> 2: When a developer tries to implement Handle<T> where T doesn't >> derive from Observable, >> he's told there is an error in: >> inline void Handle<T>::Link::linkTo(const >> boost::shared_ptr<T>& h, bool registerAsObserver) { >> A one line comment in that could warning developers that T must >> derive from Observable > > It's already in the documentation for Handle (the docs before the > class > definition.) > > Luigi > > > -- > > Zawinski's Law: > Every program attempts to expand until it can read mail. Those > programs which cannot so expand are replaced by ones which can. > > > > --- > --- > --- > --------------------------------------------------------------------- > > _______________________________________________ > QuantLib-users mailing list > [hidden email] > https://lists.sourceforge.net/lists/listinfo/quantlib-users ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
On Mon, 2010-05-24 at 10:34 +0100, Simon Courtenage wrote:
> Sorry for asking what might be a silly question but if, in Handle<T>, > T must inherit from Observable, why is Handle a template class? Because Handle must give access to the full interface of T, not only what's in Observable. If we stored a pointer to Observable, we'd have to upcast all over the place. Luigi -- There are no rules of architecture for a castle in the clouds. -- Gilbert K. Chesterton ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
In reply to this post by simoncourtenage
On Mon, 2010-05-24 at 09:20 +0100, Simon Courtenage wrote:
> On the first point, it is a good idea not to use shared_ptr > temporaries in function calls - this page > http://www.boost.org/doc/libs/1_43_0/libs/smart_ptr/shared_ptr.htm > explain why (see the section on "Best Practices") - the memory leak > would only really occur where there are two or more arguments and the > evaluation of one arg could potentially lead to an exception being > thrown, but it's still a good idea to avoid this coding practice. Yes, I'd seen the page, but thought it didn't apply here. I see your point about setting a bad example, though. Patches anyone? Luigi -- Father's got the sack from the water-works For smoking of his old cherry-briar; Father's got the sack from the water-works 'Cos he might set the water-works on fire. ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
I have another question. Doesn't Handle class duplicate the
functionality of shared_ptr? I understand, that RelinkableHandle has a whole new capability. But what Handle class can do which shared_ptr can't? Consider 2 examples below. Why would one prefer Example 2 over Example 1? In my view, they are identical unless I am missing something. Regards, Kakhkhor Abdijalilov. //====== Example 1 usig shared_ptr ====== class MyInstrument : public Observer { public: MyInstrument(const shared_ptr<Quote>& spot): spot_(spot) { registerWith(*spot_); } private: shared_ptr<Quote> spot_; }; //====== Example 2 usig Handle ====== class MyInstrument : public Observer { public: MyInstrument(const Handle<Quote>& spot): spot_(spot) { registerWith(spot_); } private: Handle<Quote> spot_; }; ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Kakhkhor Abdijalilov schrieb:
> I have another question. Doesn't Handle class duplicate the > functionality of shared_ptr? I understand, that RelinkableHandle has > a whole new capability. *But what Handle class can do which shared_ptr > can't? > * > Hi Kakhkhor, as you know class Handle is there to implement the observer pattern. Quoted from Wiki:The *observer pattern* is a software design pattern <http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29> in which an object <http://en.wikipedia.org/wiki/Object_%28computer_science%29#Objects_in_object-oriented_programming>, called the subject, maintains a list of its dependants, called observers, and notifies them automatically of any state changes, usually by calling one of their methods <http://en.wikipedia.org/wiki/Method_%28computer_science%29> ( in quantlib this is the method update). It is mainly used to implement distributed event handling systems. > Consider 2 examples below. Why would one prefer Example 2 over Example > 1? In my view, they are identical unless I am missing something. > > ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Handle class doesn't implement the observer pattern. It is linked to
an instance of Observable, but the link is permanent. Because the link is permanent, it doesn't provide any extra level of indirection. ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Kakhkhor Abdijalilov <[hidden email]> writes: > Handle class doesn't implement the observer pattern. It is linked to > an instance of Observable, but the link is permanent. Because the link > is permanent, it doesn't provide any extra level of indirection. I think this is precisely what RelinkableHandle class exists for, to decide who can relink handles and who can not. The concept is described in Luigi's document: http://luigi.ballabio.googlepages.com/appendixA.pdf And I've posted a simple example here: http://www.bnikolic.co.uk/blog/ql-handle-1-ex.html Best, Bojan -- Bojan Nikolic || http://www.bnikolic.co.uk ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Bojan Nikolic schrieb:
> Kakhkhor Abdijalilov <[hidden email]> writes: > > >> Handle class doesn't implement the observer pattern. It is linked to >> an instance of Observable, but the link is permanent. Because the link >> is permanent, it doesn't provide any extra level of indirection. >> > > I think this is precisely what RelinkableHandle class exists for, to > decide who can relink handles and who can not. > > The concept is described in Luigi's document: > > http://luigi.ballabio.googlepages.com/appendixA.pdf > > And I've posted a simple example here: > > http://www.bnikolic.co.uk/blog/ql-handle-1-ex.html > Nice example, it explains more than a thousand words. -Kim > > Best, > Bojan > > ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Thanks Bojan,
That was very helpful. Now I see that the point of using handle instead of smart pointer. Handles can be "enslaved" to a master handle which can relink them all when needed. But I've got another questions. Why Observable and Observer store their connections in std::list? Could std::set be a better choice? ------------------------------------------------------------------------------ _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
On Tue, 2010-05-25 at 18:29 -0500, Kakhkhor Abdijalilov wrote:
> But I've got another questions. Why Observable and Observer store > their connections in std::list? Could std::set be a better choice? They're probably equivalent. The only difference in behavior (*) would be if one observer registers twice with the same observable---twice directly, not indirectly (if A registers with B and C, and B registers with C, that doesn't count as A observing C twice---the two pointers to C would go in different containers.) This shouldn't happen, so I didn't give it much thought. Luigi (*) apart from list being O(1) insertion and O(N) deletion, and set being O(log N) insertion and O(log N) deletion, if I'm not mistaken. Iterating to notify all observers would be O(N) in both cases. -- There are two ways to write error-free programs; only the third one works. -- unknown ------------------------------------------------------------------------------ ThinkGeek and WIRED's GeekDad team up for the Ultimate GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the lucky parental unit. See the prize list and enter to win: http://p.sf.net/sfu/thinkgeek-promo _______________________________________________ QuantLib-users mailing list [hidden email] https://lists.sourceforge.net/lists/listinfo/quantlib-users |
Free forum by Nabble | Edit this page |