----- Original Message ----- From: "Vincent Finn" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Friday, November 22, 2002 1:38 PM Subject: [boost] Re: Formal Review Request: class optional<>
> Hi, > > I have one comment and one question. > So first the comment > > I was recently thinking about a similar thing for a slightly different > purpose. You seem to concentrate on option return values, what about > optional arguments. > > e.g. > void fn(int iImportant, optional<int> iNotImportant = optional<int>()); > > The reasoning for this is similar to for the return > the function could tell if the user had passed in an argument and act > accordingly > > Normally you can have a special default value but cases can occur where > and int is valid but none might be required. > Good point. On a few ocasions I have use optional<> to pass optional parameters. However, I've came to the following: Take you example for instance: void fn(int iImportant, optional<int> iNotImportant = optional<int>()) { if ( !!iNotImportant ) { // not important argument recieved, use it. foo ( * iNotImportant ) ; } } Since optional<> uses pointer semantics, the above code could have been written using a true pointer with nearly the same syntatic usage of the optional parameter: void fn(int iImportant, int* iNotImportant = NULL ) { if ( !!iNotImportant ) { // not important argument recieved, use it. foo ( * iNotImportant ) ; } } So, from the recieving function perspective, there is little -if any- benefit in using optional<> for this. The NULL default value for the pointer is idiomatic enough to document the fact that the parameter is optional. Now, from the caller perspective, using a pointer parameter has a drawback: the parameter must be an lvalue (it requires storage), so you can't write: fn(1,&3) and you are forced to use a local variable: int b=3; fn(1,&b); However, the true problem here is not that using a pointer in the function signature is cumbersome, but that passing it can be problematic if we want to use a literal (let's assume that prefixing '&' is not big deal). I've found more convenient to solve this specific problem instead of cluttering a function interface with optional<> as a parameter. For example, if the optional parameter is constant: void foo ( int const* x = NULL ) ; You can pass literals on the fly using the following helper: template<class T> T const& lvalue( T const& v ) { return v; } int main() { foo(&lvalue(3)); } And if the optional parameter is not constant, you can use a more sophisticated helper: template<class T> struct lvalue_wrapper { lvalue_wrapper( T val ) : data(val) {} operator T&() const { return data ; } T* operator &() const { return &data ; } mutable T data ; } ; template<class T> lvalue_wrapper<T> lvalue( T v ) { return lvalue_wrapper<T>(v) ; } void bar( int* x = NULL ) ; int main() { foo(&lvalue(3)); bar(&lvalue(3)); } Concluding, I think optional<> is not really necessary for optional parameters since these can be expressed very well by a true pointers and that the calling syntax can be arranged to be simple . > The reason I assume you don't allow for this is that your constructor is > explicit and for easier calling sytax in this case that would not be > best (I think) > i.e. I would want to be able to call the above as > fn(1, 3); > The constructor must be explicit in order to disable unexpected implicit conversions. If you happen to use optional<> in a parameter list, you can always pass it using: fn(1, optional<T>(3)); > The most common reason, though, would be the desire to use references > rather than pointers > int fn1(optional<int&> iMayNotWant = optional<int&>()); > instead of > int fn2(int* piMayNotWant = NULL); > Notice that optional<> itself has pointer semantics, so you wouldn't be able to handle "iMayNotWant" by value as you would if it were a reference; you would handle it exactly as you would if it were a true pointer. This is by it rarely makes sense to have optional<> in a parameter list. > I assume this isn't possible since references aren't default > constructable but it would be nice :-) > Actually, optional<T> does not require T to be default constructable. The reason why you can't have optional<T&> is -at least- that you cannot have a reference to a reference, and optional<T> uses "T {const} &" (for example, in the constructor). > --- > > And now the question > can this be used with VC6 ? > Yes, that's my intention. I will see to make it compile with all compilers I receive reports from. Which version of VC6 are you using? > I have tried at it won't compile (I'm compiling with boost 1.29) > I get the following error in optional > > optional_detail.hpp(91) : error C2371: 'proxy' : redefinition; different > basic types > optional_detail.hpp(90) : see declaration of 'proxy' > optional_detail.hpp(171) : see reference to class template > instantiation 'boost::optional_detail::value_based_optional<T>' being > compiled > > and lots of errors in > mpl\logical\and.hpp > e.g > mpl\logical\and.hpp(115) : error C2039: 'type' : is not a member of > '`global namespace'' > mpl\logical\and.hpp(115) : error C2146: syntax error : missing ',' > before identifier 'value' > > and a lot more :-( > > OK. I think I have a VC6.5 or some around. I'll see how to fix it. Best Regards, Fernando Cacciola _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost