Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2005-06-19 18:32:11


David Abrahams wrote:
> Tobias Schwinger <tschwinger_at_[hidden]> 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.
>

It was referring to the next sentence. "Rewinding" the discussion to one thought
before the above part of your post...

>
>>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'm not entirely sure there is, either. We agree enough, here.

>
>>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.
>

The next is not /that/ unusual (at least I've seen it in several places in Boost)...

>
>>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.

This is only a good argument if no parametrization provides better usability, I
guess ;-).

And we'll set reference decoration as the default (see further below) so you
only see it if we want something else.

>
> [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?]
>

Did you mean:

      __attribute__(__whatever__) foooooooooooooooooooooo
      ( __attribute__(__whatever__) baaaaaaaaaaaaaaaaaaaaaaar
        ( __attribute__(__whatever__) baaaaaaaaaaaaaaaaaaaaaaaaaz
        ).get_something()
      ).get_something()

;-) ? I sure would!

>
>>Sidenote: I'm not entirely sure on the MPL-Lamda expression
>
  ^ in the following section
>
> 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?

Because it hasn't been changed in documentation and the library, yet (so it's
easier to follow our discussion) and 'class' conflicts with a keyword.

>
>
>>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?"

Whoops, sorry!

I had to re-read it three times to make any sense of it, myself.
And on second though the semantics I meant are no good.

Please, just ignore 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.

Did you think about iterating the sequences...

Thanks,

Tobias


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk