
Tobias Schwinger <tschwinger@neoscientists.org> writes:
Hi Dave,
David Abrahams wrote:
I can only explain the reasons I chose a reference and not a pointer in the context of Boost.Python: pointers can be null, but references cannot, and you can never call a member function on a null pointer.
We have to start a "bit further above" ;-).
I don't know what you mean.
If we want to unify parameters and class type we have to either use a reference or a pointer to it for things to make sense.
Yes.
The by-value case (operator() member of a simple functor) is too unusual to make sense in general.
Not sure what you mean here. I don't think there's any case in which a member function can reasonably have the target object passed by value.
I also agree, that a reference is the more reasonable default.
Further, it is attractive to have a reference (as opposed to a value) in the sequence because (e.g):
// Let t be a variable of type T and some // T be some (member) function pointer/reference type function< typename function_type<plain_function,T>::type > x = t; // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // "rebinds" the subtypes of T to a plain_function
will just work.
Right.
I still don't think it is good to hard-wire this, though.
Why?
If I understand your case correctly, you want remove const qualification of the class type (which are not there, currently - but planned):
typename add_reference < typename remove_cv < typename remove_reference < typename function_type_class<T>::type // or typename at_c<sig,1>::type >::type >::type >::type
Yes, but I don't really think this library should make any special allowances for my weird case. Boost.Python may not be able to use this library anyway because of the need for vc6/7 compatibility, but if it can, I'll strip the cv-qualification myself.
Slightly better for those who want a pointer:
typename add_pointer < typename remove_reference < typename function_type_class<T>::type // or typename at_c<sig,1>::type >::type >::type
So I believe it is perhaps best to parametrize the decoartion we want on the class type:
I disagree. Too much parameterization is an impediment to usability. [BTW, so is the endline layout you're using for nested templates. There's little precedent for it anywhere that I've seen. You wouldn't write foo ( bar ( baz(1) ) ); would you?]
Sidenote: I'm not entirely sure on the MPL-Lamda expression
Your posting didn't show one above, although I can guess what the example you would have written would look like.
- we could also use some kind of tag type or an enum, I guess. Or we use MPL-Lambda exressions, but only evaluate them as a fallback when there is no optimized specialization, as for add_reference<_>, add_pointer<_> and identity<_> (maybe even one to create an unqualified reference for the Boost.Python case). Thoughts welcome.
template<typename T, typename ClassDecoration = add_reference<_> > struct function_type_signature;
template<typename T, typename ClassDecoration = add_reference<_> > struct function_type_class;
And if we want to add a unified one:
template<typename T, typename ClassDecoartion = add_reference<_> > struct function_type_effective_parameters;
(Jonathan Turkanis has suggested adding one like this. He also came up with "effective" for the name, which I happen to like).
Remind me again why you're still using the function_type_ prefix?
And perhaps even:
template<typename Tag, typename TypeOrTypes, typename ClassDecoartion = add_reference<_> > struct function_type; // ignores it, unless it specializes function_type_signature ^^ ^^ what are these? Are they the same "it?"
Revisiting the example from above we could say:
function< typename function_type<plain_function,T,add_pointer<_> >::type >
And easily even use our favourite proxy, e.g. a smart pointer...
Now that you bring that case up, parameterization starts to look a bit more attractive. I'm still leary of going in that direction, though. -- Dave Abrahams Boost Consulting www.boost-consulting.com