Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2006-11-17 12:12:24


Richard Smith wrote:
> Tobias,
>
> Sorry for not replying to your comments sooner.

Never mind - I'm happy about any movement after several days of silence :-).

>
> On Fri, 10 Nov 2006, Tobias Schwinger wrote:
>>Richard Smith wrote:
>>
>>>>> [...] instead of writing
>>>>>
>>>>> bft::is_function< T, bft::variadic >::value
>>>>>
>>>>> you would write
>>>>>
>>>>> boost:is_function<T>::value && boost::is_variadic<T>::value
>>>>
>>>>I think, I don't like it. It's too irregular for my taste.
>>>
>>>I'm not sure what exactly you mean by 'irregular'
>>
>>[...] It's the parts of the library that become asymmetric
>>between decomposition and synthesis.
>
> I'm still not entirely sure I'm following you. Do you mean
> you want two metafunctions such that
>
> synthesise< decompose<_> >
>
> is the identity?

In a way, yes.

> If so, you've already lost that because
> components doesn't store whether you have a function,
> function reference, function pointer or member function
> pointer.

Well, it does store this information, but there is no interface exposing it to the user ;-), but that's not my point.

My point is simply that you can create all the types that you can take apart.

>>>>>5. Extern "C" linkage

<snip>

>> is_function_pointer< ext_c_func_ptr, default_cc >::value
>>
>>works correctly. It tells me whether ext_c_func_ptr has
>>the C++ default calling convention.
>
> Even on a compiler (e.g. Comeau) that folds language linkage
> into the type system?

No. Thanks for making me aware of that problem! OK, now I get your point.

> On such a system, surely
>
> extern "C" typedef void (*ext_c_func_ptr)();
> is_function_pointer< ext_c_func_ptr, default_cc >::value
>
> *should* return false? (I appreciate it may not, but this
> is an problem with the implementation, albeit a problem that
> can't necessarily be solved at the moment.)

   extern "C" { void __stdcall ext_c_func() { /* ... */ } }

:-P

Actually (although the standard says something different) language linkage should tell the linker how to do symbol lookup. The only type system issue is the calling convention part and the mere existence of calling convention specifiers (which are not part of the standard, which probably explains its weirdness) actually /should/ suffice as support for type introspection.

>
> For example, in Digital Mars __cdecl and extern "C" are
> synonyms, so you already have support for it on that
> platform.
>

I'd call this ^^^ the proper way to implement things.

This problem has to be addressed, one way or the other. It is possible to check for T being a function by checking whether T* converts to void const volatile*, but that won't get us very far, but detecting is only half the rent. There is no way to take it apart, AFAICS.

I'd prefer documenting that types with external language linkage are not supported, for now.

>>>What are your thoughts on adding support for pointers to
>>>member data to the library? I guess it depends to what
>>>extra you see this as an extension to the Boost.TypeTraits
>>>library for manipulating function types, and to what extent
>>>it is viewed as a utility component for use in implementing
>>>function wrappers and so on.
>>>
>>
>>Supporting data members is trivial. So of what help could the library be?
>
>
> Consistency. TR1 defines 'callable' types to include data
> members; Boost.Function, Boost.Bind and Boost.Lambda all
> support data mebers as unary functions. The
> is_callable_builtin<> metafunctions are just for convenience
> -- they can be implemented by mpl::or_'ing together
> is_function, is_function_reference, is_function_pointer, and
> is_member_function_pointer. I'm suggesting that you should
> include is_member_object_pointer too.
>

I'm not fully convinced since that "callable builtin" term doesn't work without a definition, anyway. From my feeling data members should be handled at a higher level of abstraction (at the same place where we normalize between function objects and functions).

>>>>>10. Syntactic sugar around parameter_types
>>>>>
>>>
>>> parmeter_type< F, 0 >::type
>>>
>>
>>In that special case
>>
>> mpl::at_c<parameter_types<F>,0>::type
>>
>>isn't inconvenient enough to justify "convenience clutter"
>>in the interface, IMO.
>
>
> Well, I disagree, and I think implementing this level of
> convenience function will serve to encourage people to use
> the library.
>
>
>>I can understand the objective of keeping application code
>>free of metaprogramming magic. In this case you better
>>stay away from all metaprogramming libraries (including
>>this one and TypeTraits) and building template-based
>>interfaces altogether.
>
>
> Perhaps it's not intended to, but, frankly, that sounds
> incredibly patronising.

Certainly not intended! Did you perhaps misread me?

> I find it absolutely extraordinary
> that someone on this list would advise people who find the
> MPL intimidating to "stay away from ... building
> template-based interfaces altogether".

I'm really just citing my own style guide.

I try to separate between library and application code, keeping the latter free of templates; the application code may heavily use the library code in its implementation (.cpp) files and some library components (such as e.g. Boost.Function) may even make it to the headers. There may be exceptions to this rule, however, the more minimalist the headers look like, the better (avoid dependencies, prefer loose coupling and encapsulate by coherence - design your headers to "keep the client't compiler cool"...).

> There's a whole
> world of difference between the two;

Writing portable template code with the MPL vs. writing hopefully (but probably non-) portable template code without? Just kidding (sorry, it was just too tempting). Portability of templates is getting better, after all...

> and like it or not, in
> quite a lot of circles, the MPL *does* have a (perhaps
> largely undeserved) aura of impenetrability. I'm all for
> trying to rectify this and encourage its use, but advising
> people to avoid all template code isn't the way to achieve
> this.

Your argumentation reads like I'm forcing people to read the source of that library...

>>>>>13. Why is bft::components useful?
>>>
>>>I can't see any uses of it in the example/ directory.
>>
>>You're right. Obviously I did not remember correctly.
>
>
> Would it be possible to see a use case?
>

E.g.

    boost::function< typename function_type< components<F, shared_ptr<_> > >::type >

There are some more in this post:

    http://tinyurl.com/whkmd

>>>Sorry, which expression models which two concepts?
>>
>> components<T,ClassTransform>
>
>
> OK. And which two concepts does it model? I can see that
> it's an MPL sequence, but what else is it?

It's both a tag and an MPL sequence.

Thanks,

Tobias


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