|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 | Next > |
|
|
[smart_ptr] shared_ptr template type-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 I wonder if it might be better/possible to have a shared_ptr<T> that didn't assume its corresponding "raw" pointer type was T* but rather T. For example, what is now a shared_ptr<int> would be specified as a shared_ptr<int*>. The motivation would be to allow support for other classes as the "raw" pointer type. For example, I might want to have a shared_ptr<monitor<T*> > where the monitor<T*> has an operator->() which does automatic locking/unlocking of a mutex before/after forwarding the operator->() to the plain T pointer. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkpWA5YACgkQ5vihyNWuA4UQOwCeI7sjr4/pByXIqRtactVfi8fk MUgAoLmstL+7V5NW+yYNXyDPlVog7VAI =JE48 -----END PGP SIGNATURE----- _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeFrank Mori Hess wrote:
> I wonder if it might be better/possible to have a shared_ptr<T> that didn't > assume its corresponding "raw" pointer type was T* but rather T. For > example, what is now a shared_ptr<int> would be specified as a > shared_ptr<int*>. The motivation would be to allow support for other classes > as the "raw" pointer type. For example, I might want to have a > shared_ptr<monitor<T*> > where the monitor<T*> has an operator->() which does > automatic locking/unlocking of a mutex before/after forwarding the > operator->() to the plain T pointer. Why not having monitor_ptr< T > contain the shared_ptr and implement operator-> the way you described? Making shared_ptr templated on a pointer type is way unusual compared to other smart pointer types. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template type> I wonder if it might be better/possible to have a shared_ptr<T> that didn't > assume its corresponding "raw" pointer type was T* but rather T. If I'm not mistaken, the C++0x committee is setting the 'shared_ptr<>' class in stone as we speak. I seriously doubt that can be changed this late in the game, considering the amount of code that is already using this class as-is. See if this type of code works for you: #include <boost/shared_ptr.hpp> using boost::shared_ptr; struct mutex { void lock() {} void unlock() {} }; template< typename T > class monitor; template< typename T > class locker { mutex & mutex_; monitor< T > * monitor_; public: locker( monitor< T > * mt, mutex & mx ) : mutex_( mx ), monitor_( mt ) { mutex_.lock(); } ~locker() { mutex_.unlock(); } monitor< T > * operator->() { return monitor_; } }; template< typename T > class monitor { mutex mutex_; public: shared_ptr< T > obj_ptr; monitor( T * t ) : obj_ptr( shared_ptr< T >( t ) ) { } locker< T > operator->() { return locker< T >( this, mutex_ ); } }; int main( int argc, char * argv[] ) { char * buf = new char[ 3 ]; memset( buf, 0, 3 ); monitor< char > m( buf ); *m->obj_ptr = 'A'; return 0; } _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template type-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 On Thursday 09 July 2009, Andrey Semashev wrote: > Frank Mori Hess wrote: > > I wonder if it might be better/possible to have a shared_ptr<T> that > > didn't assume its corresponding "raw" pointer type was T* but rather T. > > For example, what is now a shared_ptr<int> would be specified as a > > shared_ptr<int*>. The motivation would be to allow support for other > > classes as the "raw" pointer type. For example, I might want to have a > > shared_ptr<monitor<T*> > where the monitor<T*> has an operator->() which > > does automatic locking/unlocking of a mutex before/after forwarding the > > operator->() to the plain T pointer. > > Why not having monitor_ptr< T > contain the shared_ptr and implement > operator-> the way you described? Yes, that is in fact what I did: http://www.comedi.org/projects/libpoet/boostbook/doc/boostbook/html/poet/monitor_ptr.html However, it seems like more work to have to provide a full shared_ptr interface, than to implement a plain pointer interface. And perhaps more significantly, a monitor_ptr is a completely different type than a shared_ptr. So, for example, a monitor_ptr can't be passed to a function that expects a shared_ptr as an argument. Also, if there are other applications for pointer wrapper classes, they could be mixed an matched in any combination by the end user in this scheme, like shared_ptr<monitor<pointer_wrapper<T*> > > Maybe, for example, a pointer wrapper class might enforce that the wrapped pointer may never be NULL, to implement a shared_ptr that acts something like a "smart reference". -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkpWLu4ACgkQ5vihyNWuA4WFAgCgj2hnsj5uZs1R78+YI2UVVLz0 0tYAoKLA67xb4pgNJXSkr9XbO+Hi7pcH =2OvX -----END PGP SIGNATURE----- _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template type-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 On Thursday 09 July 2009, Sid Sacek wrote: > > I wonder if it might be better/possible to have a shared_ptr<T> that > > didn't > > > assume its corresponding "raw" pointer type was T* but rather T. > > If I'm not mistaken, the C++0x committee is setting the 'shared_ptr<>' > class in stone as we speak. I seriously doubt that can be changed this > late in the game, considering the amount of code that is already using > this class as-is. I'm not under any delusions about getting such a change to std::shared_ptr into c++0x. That doesn't preclude something like this being added to boost though, under a different name (I'll call it "generalized_shared" for the moment). Then boost::shared_ptr could be implemented as template<typename T> class shared_ptr: public generalized_shared<T*> {...}; -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkpWL90ACgkQ5vihyNWuA4Uk2ACcDr+WxE2Ku00ljjQRnUB+1n/c m4EAnjYLI/S+5KyIgopMyLFrI9xX10vB =cOH8 -----END PGP SIGNATURE----- _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeThis was fun to experiment with. Here's another whack at your puzzle.
-Sid Sacek #include <iostream> #include <boost/shared_ptr.hpp> using namespace std; using boost::shared_ptr; template< typename T > class monitor; template< typename T > class locker { shared_ptr< T > shared_obj_; public: locker( shared_ptr< T > &shared_obj ) : shared_obj_( shared_obj ) { shared_obj_->lock(); } ~locker() { shared_obj_->unlock(); } shared_ptr< T > operator->() { return shared_obj_; } }; template< typename T > class monitor { shared_ptr< T > shared_obj_; public: monitor( T * t ) : shared_obj_( shared_ptr< T >( t ) ) { } locker< T > operator->() { return locker< T >( shared_obj_ ); } }; struct mutex { void lock() { cout << "object locked \n"; } void unlock() { cout << "object unlocked \n"; } }; struct Q : mutex { void ModifyObject() { cout << "Object modified \n"; } }; int main( int argc, char * argv[] ) { monitor< Q > m( new Q ); m->ModifyObject(); return 0; } _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeOn Thursday, July 9, 2009, Frank Mori Hess <frank.hess@...> wrote:
> -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > > I wonder if it might be better/possible to have a shared_ptr<T> that didn't > assume its corresponding "raw" pointer type was T* but rather T. For > example, what is now a shared_ptr<int> would be specified as a > shared_ptr<int*>. The motivation would be to allow support for other classes > as the "raw" pointer type. For example, I might want to have a > shared_ptr<monitor<T*> > where the monitor<T*> has an operator->() which does > automatic locking/unlocking of a mutex before/after forwarding the > operator->() to the plain T pointer. I don't think lock/unlock on each -> call is typically a good idea. x = p->x; y = p->y; That's 2 lock unlock sequences instead of one. Inefficient and what if y changes after you read x? It hides the locking too much, potentially leading to abuse and mistakes. I think alexandrescu has an article about this somewhere. (he also has articles about how to implement locking -> operators but I think he later recanted on the whole idea) Tony _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template type-----Original Message----- From: boost-bounces@... [mailto:boost-bounces@...] On Behalf Of Gottlob Frege > I don't think lock/unlock on each -> call is typically a good idea. > x = p->x; > y = p->y; > That's 2 lock unlock sequences instead of one. Inefficient and what > if y changes after you read x? > It hides the locking too much, potentially leading to abuse and mistakes. > > Tony I agree and disagree. I would at some point want to create a class similar to what's being described, but would not expose it to the rest of the world to use ( and abuse ). A class like that could come in handy, as long as it's used with the knowledge of its strengths and limitations. -Sid Sacek _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeSid Sacek wrote:
> From: boost-bounces@... > [mailto:boost-bounces@...] On Behalf Of Gottlob Frege > > > I don't think lock/unlock on each -> call is typically a good > > idea. > > x = p->x; > > y = p->y; > > That's 2 lock unlock sequences instead of one. Inefficient > > and what if y changes after you read x? > > It hides the locking too much, potentially leading to abuse > > and mistakes. > > I agree and disagree. I would at some point want to create a > class similar to what's being described, but would not expose > it to the rest of the world to use ( and abuse ). A class like > that could come in handy, as long as it's used with the > knowledge of its strengths and limitations. Tony's on target. You've said you wanted the class to be a shared_ptr, which means it can be used in myriad ways without even knowing the cost. If it were a distinct type, then it couldn't be unknowingly misused. Such a type, were you to create it, should not be a special version of shared_ptr. That also avoids forking relative to C++0x. _____ Rob Stewart robert.stewart@... Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template type-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 On Thursday 09 July 2009, Gottlob Frege wrote: > On Thursday, July 9, 2009, Frank Mori Hess <frank.hess@...> wrote: > > -----BEGIN PGP SIGNED MESSAGE----- > > Hash: SHA1 > > > > > > I wonder if it might be better/possible to have a shared_ptr<T> that > > didn't assume its corresponding "raw" pointer type was T* but rather T. > > For example, what is now a shared_ptr<int> would be specified as a > > shared_ptr<int*>. The motivation would be to allow support for other > > classes as the "raw" pointer type. For example, I might want to have a > > shared_ptr<monitor<T*> > where the monitor<T*> has an operator->() which > > does automatic locking/unlocking of a mutex before/after forwarding the > > operator->() to the plain T pointer. > > I don't think lock/unlock on each -> call is typically a good idea. > x = p->x; > y = p->y; > That's 2 lock unlock sequences instead of one. Inefficient and what > if y changes after you read x? > It hides the locking too much, potentially leading to abuse and mistakes. My monitor_ptr also supports scoped locks, so multiple calls can be made into the object with one lock/unlock: http://www.comedi.org/projects/libpoet/boostbook/doc/boostbook/html/poet/monitor_ptr.html e.g: monitor_ptr<X> mp; { monitor_unique_lock<monitor_ptr<int> > lock(mp); //locks mutex lock->f();// calls X::f lock->g(); }// lock destruction unlocks mutex However, I was hoping to discuss a generalization of shared_ptr more, I mainly brought up monitors as a motivating example. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkpWOiYACgkQ5vihyNWuA4VUTACg4MtjHL+bPqwLH/1qjp7YzKP1 TgIAn3dm4chUiv2iqgpi+L+gIUlsiMRq =kKfs -----END PGP SIGNATURE----- _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeFrank Mori Hess wrote:
> On Thursday 09 July 2009, Andrey Semashev wrote: >> Why not having monitor_ptr< T > contain the shared_ptr and implement >> operator-> the way you described? > > Yes, that is in fact what I did: > > http://www.comedi.org/projects/libpoet/boostbook/doc/boostbook/html/poet/monitor_ptr.html > > However, it seems like more work to have to provide a full shared_ptr > interface, than to implement a plain pointer interface. You don't have to reimplement shared_ptr interface, unless you really need it. And that interface isn't that sophisticated, anyway. > And perhaps more > significantly, a monitor_ptr is a completely different type than a > shared_ptr. So, for example, a monitor_ptr can't be passed to a function > that expects a shared_ptr as an argument. Types shared_ptr<monitor<T*> >, shared_ptr<T*> and shared_ptr<T> are not compatible either, so you don't win here anything. > Also, if there are other applications for pointer wrapper classes, they could > be mixed an matched in any combination by the end user in this scheme, like > > shared_ptr<monitor<pointer_wrapper<T*> > > > > Maybe, for example, a pointer wrapper class might enforce that the wrapped > pointer may never be NULL, to implement a shared_ptr that acts something like > a "smart reference". IMHO, one of the remarkable features of shared_ptr is its simplicity. All additional features that you describe, while being useful, are out of scope of this simple tool. I agree that some more elaborate policy-driven smart pointer would be useful to implement those things. It just isn't related to shared_ptr in any way. IIRC, Andrei Alexandrescu tried to develop such a pointer, I'm not sure how successful he was. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template type-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 On Thursday 09 July 2009, Andrey Semashev wrote: > Frank Mori Hess wrote: > > And perhaps more > > significantly, a monitor_ptr is a completely different type than a > > shared_ptr. So, for example, a monitor_ptr can't be passed to a function > > that expects a shared_ptr as an argument. > > Types shared_ptr<monitor<T*> >, shared_ptr<T*> and shared_ptr<T> are not > compatible either, so you don't win here anything. That's mostly true, however suppose you have a function like template<typename T> myfunc(shared_ptr<T> sp); You might say it could be replaced with something more generic like template<typename SharedPtr> myfunc(SharedPtr sp); but perhaps myfunc creates a weak_ptr<T> from the incoming parameter. The more generic version won't work because shared_ptr doesn't include a typedef for its corresponding weak_ptr type. Also, the more generic version of myfunc might cause conflicts if myfunc has other overloads. You'd be forced to add specialized code for each additional shared_ptr-like class you introduce, or something like type traits for them. > IMHO, one of the remarkable features of shared_ptr is its simplicity. I agree. > All additional features that you describe, while being useful, are out > of scope of this simple tool. I agree that some more elaborate > policy-driven smart pointer would be useful to implement those things. > It just isn't related to shared_ptr in any way. Perhaps I should have distanced my idea from shared_ptr more in presenting it, as I know making interface changes to shared_ptr is almost unthinkable at this point. But it's obviously a related idea, in that generalized_shared<T*> would be equivalent to shared_ptr<T>. And also I imagine generalized_shared could be implemented by copying the entire shared_ptr codebase and then making only minor changes. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkpWT/0ACgkQ5vihyNWuA4U1RACggaAZopOtBZj2Nv2X58JdCL/D g1kAoIvAa/D9e1c6N5Z4jfbWgVk3FuZZ =5jFA -----END PGP SIGNATURE----- _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeFrank Mori Hess wrote:
> And also I imagine generalized_shared could be implemented by copying > the entire shared_ptr codebase and then making only minor changes. shared_count can already take an arbitrary P/D pair, so you only need to copy shared_ptr itself, not the rest of the codebase. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template type-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1 On Friday 10 July 2009, Peter Dimov wrote: > Frank Mori Hess wrote: > > And also I imagine generalized_shared could be implemented by copying > > the entire shared_ptr codebase and then making only minor changes. > > shared_count can already take an arbitrary P/D pair, so you only need to > copy shared_ptr itself, not the rest of the codebase. Ah, ok. Based on your encouragement (at least in the relative sense, since everyone else's response has been negative :), I've implemented a first pass at generic_shared. For those just tuning in generic_shared is like a shared_ptr but can accept a more generic type as the "pointer". It can accept either a plain old pointer as its template type, or a class which: 1) has operator->() and operator*() 2) either has value_type/reference/pointer member typedefs, or a specialization of boost::smart_pointer_traits 3) has a is_null_pointer() free function findable by ADL 4) supports (in)equality comparison generic_shared can also be used by another smart pointer class with similar requirements, since it fulfills them all itself. So you could have monitor<generic_shared<T*> > , to bring back the monitor example. The code is in the file generic_shared.hpp (a fork of shared_ptr.hpp from trunk) which is located in the sandbox directory: https://svn.boost.org/trac/boost/browser/sandbox/fmhess/boost/smart_ptr The file can be copied into the main boost tree (I've been testing it with trunk). There is also a shared_ptr.hpp in the same directory, which implements shared_ptr on top of generic_shared. I used that mainly so I could do some testing of generic_shared using the shared_ptr tests unmodified. The tests pass, except for those which use enabled_shared_from_this or weak_ptr. Beyond that, I've played around a little with a few basic tests that use a user-defined pointer type, and also use a list iterator as the pointer type (with a deleter that uses the iterator to erase the element from its list). So, the current status is: no generic_weak (analogous to weak_ptr) yet, and no shared_from_this support. Also, there is an unresolved issue with respect to casting for non-plain old pointer types. generic_shared tries to apply boost::static/const/dynamic_pointer_cast to its pointer type, but ADL doesn't work for boost::static/const/dynamic_pointer_cast, and specialization won't work either. It seems I'll need to add a ADL hook for casts as suggested at the end of this thread: http://lists.boost.org/Archives/boost/2006/06/106406.php so user-defined pointer types can be support casting. So, before I spend any more time on it, is this something worth pursuing further as far as boost goes? Does it stand any chance of making it into the smart_ptr library? Is there a silent majority out there who thinks this is a worthwhile idea, or is it just me? I might even settle for a vocal minority :) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkpc0TMACgkQ5vihyNWuA4VC6ACfW9UfTkCHTbmPc8a+VH2oFU/c XDEAn2B8wckssSMUL9yK1XUqZPfCyl1r =u9n9 -----END PGP SIGNATURE----- _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeOn Tue, Jul 14, 2009 at 1:40 PM, Frank Mori Hess<frank.hess@...> wrote:
> So, before I spend any more time on it, is this something worth pursuing > further as far as boost goes? Does it stand any chance of making it into the > smart_ptr library? Is there a silent majority out there who thinks this is a > worthwhile idea, or is it just me? I might even settle for a vocal > minority :) I would use the heck out of something like this. However I was disappointed to see in the comments that the null_value member was replaced by a search for a free function lookup. If traits are going to be supported at all, I think they should be supported first-class, and allow one to just parameterize the class with a traits class to begin with. Every example in boost that I can think of off the top of my head where something relies on either a free-function overload or a template specialization of something (which admittedly isn't too many, but at least 2 or 3 anyway) I have always encountered limitations in in my own usage and had to roll my own similar class for some specialized usage. Maybe this has been discussed in similar contexts before and there's some general consensus, but why not just (note this code assumes that all specializations of smart_pointer_traits in the version in sandbox remain unchanged): template<class T> struct default_smart_pointer_traits : public smart_pointer_traits<T> { static bool is_null(pointer p) { return (p == 0) ? true : false; } }; template<class T, class Traits=default_smart_pointer_traits<T> > class generic_shared { }; As long as the interface required of a traits class is very small, then the class still remains equally simple to use. I don't have an immediate use case in mind for wanting two different instances of generic_shared<> to check for NULL differently, but I know I've been burned more than once in the past by classes requiring free function overloads, so I just want to address it in advance. Zach _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeZachary Turner wrote:
> On Tue, Jul 14, 2009 at 1:40 PM, Frank Mori Hess<frank.hess@...> wrote: >> So, before I spend any more time on it, is this something worth pursuing >> further as far as boost goes? Does it stand any chance of making it into the >> smart_ptr library? Is there a silent majority out there who thinks this is a >> worthwhile idea, or is it just me? I might even settle for a vocal >> minority :) > > I would use the heck out of something like this. However I was > disappointed to see in the comments that the null_value member was > replaced by a search for a free function lookup. If traits are going > to be supported at all, I think they should be supported first-class, > and allow one to just parameterize the class with a traits class to > begin with. It's interesting you should say that, because I have had exactly the reverse experience. I find free function overloads much superior to traits classes for simple things like this. For example, I think boost::hash is better than std::hash because it uses a free function and ADL to find the hashes of my classes. The main advantage is the possibility of using enable_if which allows one function overload to apply to many classes. Can you be more explicit about the problems you have had? John Bytheway _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeOn Tue, Jul 14, 2009 at 4:42 PM, John Bytheway<jbytheway+boost@...> wrote:
> Zachary Turner wrote: >> On Tue, Jul 14, 2009 at 1:40 PM, Frank Mori Hess<frank.hess@...> wrote: >>> So, before I spend any more time on it, is this something worth pursuing >>> further as far as boost goes? Does it stand any chance of making it into the >>> smart_ptr library? Is there a silent majority out there who thinks this is a >>> worthwhile idea, or is it just me? I might even settle for a vocal >>> minority :) >> >> I would use the heck out of something like this. However I was >> disappointed to see in the comments that the null_value member was >> replaced by a search for a free function lookup. If traits are going >> to be supported at all, I think they should be supported first-class, >> and allow one to just parameterize the class with a traits class to >> begin with. > <snip> > > It's interesting you should say that, because I have had exactly the > reverse experience. I find free function overloads much superior to > traits classes for simple things like this. For example, I think > boost::hash is better than std::hash because it uses a free function and > ADL to find the hashes of my classes. The main advantage is the > possibility of using enable_if which allows one function overload to > apply to many classes. Can you be more explicit about the problems you > have had? > The most recent experience I had is in regards to providing custom validators for types in boost::program_options. I actually made a thread about this a day or two ago on this list, which you can probably find in the most recent 20 or 30 threads. But the gist of it is that I wanted to allow the user to specify an integer on the command line, and I wanted to enforce that the integer was within a certain range. Since boost::program_options has built-in support for validation I figured I'd use it. But, validation is enabled by a free-function overload on the type of the parameter. so you can provide validation for ints, validations for Foo's, etc, but you can't provide validation algorithm A for this specific command line option, and validation algorithm B for that specific command line option. It's not hard to just wait until the entire thing has been parsed and then check that each one it's in a certain range, but still, builtin support for validation has been implemented, so it would be nice if it was generic enough to handle a wide variety of validation scenarios. Another experience I had which I also made a thread about a week or so ago was with regards to intrusive_ptr. Turns out that what I wanted wasn't _technically_ covered by the design goals of intrusive_ptr, but nonetheless it would have been possible if intrusive_ptr used ref_counting_traits with a compile-time interface mandating an add_ref and release function, rather than free function overloads. I basically wanted a way to provide different strategies for managing the same reference count on different instances of the same type. There was at least one other scenario where I was burned by this, but I can't remember it off the top of my head as it was quite a while ago. Regarding enable_if, I didn't actually think of that. But is there a reason that if the generic class in question uses a default traits class as I suggested, that a user cannot simply provide a template specialization of that same class that uses the class template version of enable_if to achieve a similar effect? _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeOn Tue, Jul 14, 2009 at 6:04 PM, Zachary Turner<divisortheory@...> wrote:
> On Tue, Jul 14, 2009 at 4:42 PM, John Bytheway<jbytheway+boost@...> wrote: >> Zachary Turner wrote: >>> On Tue, Jul 14, 2009 at 1:40 PM, Frank Mori Hess<frank.hess@...> wrote: >>>> So, before I spend any more time on it, is this something worth pursuing >>>> further as far as boost goes? Does it stand any chance of making it into the >>>> smart_ptr library? Is there a silent majority out there who thinks this is a >>>> worthwhile idea, or is it just me? I might even settle for a vocal >>>> minority :) >>> >>> I would use the heck out of something like this. However I was >>> disappointed to see in the comments that the null_value member was >>> replaced by a search for a free function lookup. If traits are going >>> to be supported at all, I think they should be supported first-class, >>> and allow one to just parameterize the class with a traits class to >>> begin with. >> <snip> >> >> It's interesting you should say that, because I have had exactly the >> reverse experience. I find free function overloads much superior to >> traits classes for simple things like this. For example, I think >> boost::hash is better than std::hash because it uses a free function and >> ADL to find the hashes of my classes. The main advantage is the >> possibility of using enable_if which allows one function overload to >> apply to many classes. Can you be more explicit about the problems you >> have had? >> > > The most recent experience I had is in regards to providing custom > validators for types in boost::program_options. I actually made a > thread about this a day or two ago on this list, which you can > probably find in the most recent 20 or 30 threads. But the gist of it > is that I wanted to allow the user to specify an integer on the > command line, and I wanted to enforce that the integer was within a > certain range. Since boost::program_options has built-in support for > validation I figured I'd use it. But, validation is enabled by a > free-function overload on the type of the parameter. so you can > provide validation for ints, validations for Foo's, etc, but you can't > provide validation algorithm A for this specific command line option, > and validation algorithm B for that specific command line option. > It's not hard to just wait until the entire thing has been parsed and > then check that each one it's in a certain range, but still, builtin > support for validation has been implemented, so it would be nice if it > was generic enough to handle a wide variety of validation scenarios. > > > Another experience I had which I also made a thread about a week or so > ago was with regards to intrusive_ptr. Turns out that what I wanted > wasn't _technically_ covered by the design goals of intrusive_ptr, but > nonetheless it would have been possible if intrusive_ptr used > ref_counting_traits with a compile-time interface mandating an add_ref > and release function, rather than free function overloads. I > basically wanted a way to provide different strategies for managing > the same reference count on different instances of the same type. > There was at least one other scenario where I was burned by this, but > I can't remember it off the top of my head as it was quite a while > ago. > > Regarding enable_if, I didn't actually think of that. But is there a > reason that if the generic class in question uses a default traits > class as I suggested, that a user cannot simply provide a template > specialization of that same class that uses the class template version > of enable_if to achieve a similar effect? My standard answer has now become: 1. use a traits/policy class 2. have the default traits/policy call a free functinon eg: // default free function // or yours will found by ADL if you supply your own // template<class T> bool is_null_pointer(T p) { return (p == 0); }; // default policy class, calls whatever it finds by ADL // feel free to supply your own policy class instead // template<class T> struct default_smart_pointer_traits : public smart_pointer_traits<T> { static bool is_null(pointer p) { return is_null_pointer(p); } }; Tony _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeZachary Turner wrote:
> On Tue, Jul 14, 2009 at 4:42 PM, John > Bytheway<jbytheway+boost@...> wrote: > > Zachary Turner wrote: > > > It's interesting you should say that, because I have had > > exactly the reverse experience. I find free function > > overloads much superior to traits classes for simple things > > like this. For example, I think boost::hash is better than > > std::hash because it uses a free function and ADL to find the > > hashes of my classes. The main advantage is the possibility > > of using enable_if which allows one function overload to apply > > to many classes. Can you be more explicit about the problems > > you have had? > > The most recent experience I had is in regards to providing > custom validators for types in boost::program_options. I > actually made a thread about this a day or two ago on this > list, which you can probably find in the most recent 20 or 30 > threads. But the gist of it is that I wanted to allow the user > to specify an integer on the command line, and I wanted to > enforce that the integer was within a certain range. Since > boost::program_options has built-in support for validation I > figured I'd use it. But, validation is enabled by a > free-function overload on the type of the parameter. so you > can provide validation for ints, validations for Foo's, etc, > but you can't provide validation algorithm A for this specific > command line option, and validation algorithm B for that > specific command line option. It's not hard to just wait until > the entire thing has been parsed and then check that each one > it's in a certain range, but still, builtin support for > validation has been implemented, so it would be nice if it was > generic enough to handle a wide variety of validation > scenarios. I don't think there is a single best way to handle customization. It depends upon whether a class template or a function template is being customized, at the least. Neither traits classes nor customization functions are as flexible as policy classes for class templates. A class template can be parameterized with a policy, likely defaulted to something reasonable, which defines the desired behavior once for all uses of that type. Being a policy class, however, the default can be overridden. The same is not true for traits. For function templates, however, a policy class isn't as convenient as the other options because it must be provided for each invocation, even when the default is wanted. A function template could accept a defaulted functor argument, of course, though deviating from the default requires passing the functor for each invocation. I suspect the desired parameter validation scheme requires providing a functor when defining a particular parameter. That's not onerous since each parameter is registered just once. The same approach would be a problem with a hash function, however. That scenario probably is better served by a hashing function object that relies on a policy class to control the behavior of its function call operator (a set-it-and-forget-it approach). > Regarding enable_if, I didn't actually think of that. But is > there a reason that if the generic class in question uses a > default traits class as I suggested, that a user cannot simply > provide a template specialization of that same class that uses > the class template version of enable_if to achieve a similar > effect? I was wondering the same. _____ Rob Stewart robert.stewart@... Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
|
|
Re: [smart_ptr] shared_ptr template typeGottlob Frege wrote:
> > My standard answer has now become: > 1. use a traits/policy class > 2. have the default traits/policy call a free functinon > > eg: > > // default free function > // or yours will found by ADL if you supply your own > // > template<class T> bool is_null_pointer(T p) > { > return (p == 0); > }; > > // default policy class, calls whatever it finds by ADL > // feel free to supply your own policy class instead > // > template<class T> struct default_smart_pointer_traits > : public smart_pointer_traits<T> > { > static bool is_null(pointer p) > { > return is_null_pointer(p); > } > }; That's a very nice approach. You seem to lump traits and policy classes together, but they are clearly not equivalent. I think a policy class is superior to a traits class, so your numbered bullets should not contain "traits/". What about function templates? The above seems to apply to class templates only. Overloading permits one function template to rely on a default functor type while another can take a functor as an argument. (The former can call the latter, of course.) The functor argument can be defaulted, provided the default functor is stateless. _____ Rob Stewart robert.stewart@... Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com _____ Rob Stewart robert.stewart@... Software Engineer, Core Software using std::disclaimer; Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses. _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost |
| < Prev | 1 - 2 | Next > |
| Free embeddable forum powered by Nabble | Forum Help |