|
Boost : |
From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2005-06-19 14:39:01
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" ;-).
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.
The by-value case (operator() member of a simple functor) is too unusual to make
sense in general.
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.
I still don't think it is good to hard-wire this, though.
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
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:
Sidenote: I'm not entirely sure on the MPL-Lamda expression - 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).
And perhaps even:
template<typename Tag, typename TypeOrTypes,
typename ClassDecoartion = add_reference<_> >
struct function_type;
// ignores it, unless it specializes function_type_signature
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...
Hoping to get a clear image on how the optimal synopsis of the library has to
look like, I'm looking forward to read your comments.
Thanks,
Tobias
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk