[function_types] Review Result

The Library ~~~~~~~~ Function Types library by Tobias Schwinger Available from the sandbox at: http://boost-sandbox.sourceforge.net/vault/ or the zip file is: http://boost-sandbox.sourceforge.net/vault/index.php?action=downloadfile&filename=function_types.zip&directory=& This library provides a metaprogramming facility to classify, decompose and synthesize function-, function pointer-, function reference- and member function pointer types. For the purpose of this documentation, these types are collectively referred to as function types (this differs from the standard definition and redefines the term from a programmer's perspective to refer to the most common types that involve functions). The classes introduced by this library shall conform to the concepts of the Boost Metaprogramming library (MPL). The Function Types library enables the user to: * test an arbitrary type for being a function type of specified kind, * inspect properties of function types, * view and modify sub types of an encapsulated function type with MPL Sequence operations, and * synthesize function types. This library supports variadic functions and can be configured to support non-default calling conventions. Review Summary ~~~~~~~~~~~~ The function types review took place between the 6th and the 20th June 2005. There were 4 reviews, three reviewers made tentative "yes" votes. The review manager abstained. The reviewers took the view that the library was useful, but had issues with: * The naming and organisation of some components (particularly the tag types). * The scope of the test cases. * The documentation: in particular many reviewers had difficulty understanding the motivation behind the library, and felt that the documentation would put off many potential new users. Tobias and the reviewers alike have tried hard to correct this, but it's apparent that writing really clear documentation for this library is actually quite a difficult task (basically we've all been struggling to come up with really easy to understand terminology that can be applied here, what the library does isn't that hard to understand once you have "got it", but there is a lack of accepted terminology for what the library does which makes it hard to write documentation that will allow a newbe to "get it" in the first place). Proposed Changes ~~~~~~~~~~~~~ Tobias has been very proactive in dealing with the issues that have come up during the review period, and has already published a list of proposed changes to address the reviewers concerns: http://lists.boost.org/boost/2005/06/29005.php http://lists.boost.org/boost/2005/06/29006.php http://lists.boost.org/boost/2005/06/29007.php Review Result ~~~~~~~~~~ There was some concern on the part of the review manager that not many reviews were submitted for this library. We don't have a hard and fast rule on how many positive reviews are enough to justify inclusion of a library, but there does seem to have been a decline in the number of reviews received for libraries recently. Partly this may be down to the fact that we have a release going on as well at present, also this library is probably mainly of interested to other library authors (who are busy with the release!). It's also possible that the problems some reviewers had in grasping all the concepts behind the library put some people off from contributing (this issue will be addressed by Tobias' proposed documentation changes however). So..... after some consultation with the other moderators (on how many reviews constitute "enough").... the result: the function types library is accepted into Boost, subject to a further mini-review to be conducted at a later time convenient to Tobias. The "mini review" will be conducted independently to the full review process; it's purpose will not be to reopen issues already addressed at this review, but to give reviewers a chance to: * Check the reorganised/renamed classes: there are enough changes here to make the library look-and-feel different even if the changes are actually largely cosmetic. It's important that we get this right, as meta-function naming can have a large (albeit subjective) impact on usability. * Check the revised documentation. As noted above, several people have had an attempt at revising this, and it's surprisingly hard to get right. There are enough changes coming here to make the new docs substantially different from those that the reviewers looked at. Regards, John Maddock [function types review manager]

John Maddock wrote:
[...]
Proposed Changes ~~~~~~~~~~~~~
Tobias has been very proactive in dealing with the issues that have come up during the review period, and has already published a list of proposed changes to address the reviewers concerns:
http://lists.boost.org/boost/2005/06/29006.php ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Update: http://lists.boost.org/boost/2005/06/29469.php

Tobias Schwinger wrote:
John Maddock wrote:
[...]
Proposed Changes ~~~~~~~~~~~~~
Tobias has been very proactive in dealing with the issues that have come up during the review period, and has already published a list of proposed changes to address the reviewers concerns:
Updated: http://lists.boost.org/boost/2005/07/29659.php
Updated: http://lists.boost.org/boost/2005/07/29657.php
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Tobias Schwinger wrote:
Tobias Schwinger wrote:
John Maddock wrote:
[...]
Proposed Changes ~~~~~~~~~~~~~
Tobias has been very proactive in dealing with the issues that have come up during the review period, and has already published a list of proposed changes to address the reviewers concerns:
Documentation preview (includes three sections): http://tinyurl.com/dg68y (not yet hyperlinked)
Updated: http://lists.boost.org/boost/2005/07/29657.php
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Tobias Schwinger wrote:
Documentation preview (includes three sections): http://tinyurl.com/dg68y (not yet hyperlinked)
Boost.FunctionTypes provides functionality to classify, decompose and synthesize function types and other compound types such as pointer-, reference- and pointer to member function types. This means in other words to Excuse me butting in, but I'd change the sentence above to: In other words, the library can be used to Further down the page you have: Just like Boost.TypeTraits, the Function Types library works on built-in types. In contrast to Type Traits, however, it specializes in the manifold properties of callable builtin types. I don't know what you mean by "the manifold properties of". I'll return to lurking mode now ;-) Angus

Angus Leeming wrote:
Tobias Schwinger wrote:
Documentation preview (includes three sections): http://tinyurl.com/dg68y (not yet hyperlinked)
Boost.FunctionTypes provides functionality to classify, decompose and synthesize function types and other compound types such as pointer-, reference- and pointer to member function types.
This means in other words to
Excuse me butting in, but I'd change the sentence above to:
In other words, the library can be used to
OK. Better.
Further down the page you have:
Just like Boost.TypeTraits, the Function Types library works on built-in types. In contrast to Type Traits, however, it specializes in the manifold properties of callable builtin types.
I don't know what you mean by "the manifold properties of".
Well, the following text probably clears it up... Btw. did you perhaps overlook there are two more pages? Thanks, Tobias

Tobias Schwinger wrote:
Further down the page you have:
Just like Boost.TypeTraits, the Function Types library works on built-in types. In contrast to Type Traits, however, it specializes in the manifold properties of callable builtin types.
I don't know what you mean by "the manifold properties of".
Well, the following text probably clears it up...
Sorry, but I don't think that that is good enough. The first thing that people are going to read is this introductory page, so it has to be accessible.
Btw. did you perhaps overlook there are two more pages?
I'll have a look at them over the w/e if you like. Angus

Angus Leeming wrote:
Tobias Schwinger wrote:
Further down the page you have:
Just like Boost.TypeTraits, the Function Types library works on built-in types. In contrast to Type Traits, however, it specializes in the manifold properties of callable builtin types.
I don't know what you mean by "the manifold properties of".
Well, the following text probably clears it up...
Sorry, but I don't think that that is good enough. The first thing that people are going to read is this introductory page, so it has to be accessible.
OK. It's actually just "text flow decoration" here. Let's just strike it.
Btw. did you perhaps overlook there are two more pages?
I'll have a look at them over the w/e if you like.
Great! Thanks, Tobias

From: Tobias Schwinger <tschwinger@neoscientists.org>
Documentation preview (includes three sections):
http://tinyurl.com/dg68y (not yet hyperlinked)
________________________________
Overview
Boost.FunctionTypes provides functionality to classify, decompose and synthesize function types and other compound types such as ^^^ ^^^ A prime example of why one really should always use the extra comma in a series. There can be no confusion when you do so.
...classify, decompose, and synthesize function types and other....
pointer-, reference- and pointer to member function types.
I don't get what "pointer-" and "reference-" are supposed to be joined with to make that phrase work. There are function pointer types and function reference types, but there are no "pointer-function types" or "reference-function types." I'm assuming you meant this: ...types such as function pointer, function reference, and member function pointer types.
This means in other words to
This means you can > * test whether a type is a specific callable builtin type, ...specific, callable, built-in type; Note the trailing semicolon. Since some items in your list have commas, you need to use semicolons to separate the list items. Note also that "builtin" should be "built-in." > * inspect function properties such as arity, kind, result- and parameter types, and You haven't defined "kind," so it's not helpful here. What's "result-" supposed to connect to? * inspect function properties such as arity, result type, parameter types, etc.; and > * create callable builtin types from specified function properties. ...callable, built-in types....
it specializes in the manifold properties of callable builtin types.
As someone else wrote, "manifold properties" is almost inscrutable to me. While the usage is correct, the word is rarely used as an adjective. s/builtin/built-in/ it specializes in the many properties of callable built-in types. _____________________________________
Introduction
About 300 overloads are needed for three different calling conventions and a maximum arity of 10. This calculation is
You haven't mentioned "calling conventions" before this. Shouldn't that be in the table?
simplified and more irregular in reality.
s/and more/and is more/
* it can lead to a noticable slowdown,
* can be slower, (If not, fix the spelling of "noticeable.")
This is why Boost.FunctionTypes factors it out and allows ^^ Missing antecendent.
client code to arbitrarily classify and decompose any of the type's multi-faceted properties:
Boost.FunctionTypes addresses those disadvantages and allows your code to arbitrarily classify and decompose any of a function type's properties. The example becomes much simpler as the function template's template argument list and formal parameter type are reduced to "T":
It can be desirable to transform callable built-in types. This
In other situations, you may need to transform from one callable built-in type to another.
is especially useful together with Boost.Function. The next example shows specializing boost::function to store an arbitrary callable scalar f of type F.
This example illustrates how to specialize boost::function to store an arbitrary, callable scalar f of type F: The example for that should really build upon the previous example: template<typename F> void facility::register_function(F f) { boost::function<typename function_type<F>::type> wrapped = f; // call wrapped as appropriate }
An opportunity for optimization is to transform the signature changing by-value parameters to use constant references to avoid duplicate copy-construction when the boost::function object's parentheses operator is called (the fact that adding a reference can be inefficient for small sized objects is ignored for the sake of simplicity here).
Too long and missing at least a comma. It also doesn't guide the reader enough. A common optimization, when forwarding parameters from one function to another, is to transform by-value parameters to references to const. This avoids creating superfluous copies when one function calls another. In our example, if register_function() takes the argument types from its template argument F and uses them to declare the boost::function object f. If F includes by-value parameters, then register_function() will create superfluous copies of its arguments when calling f. Ideally, we want f to take its arguments by reference to const to avoid those copies. (For simplicity's sake, we ignore the fact that passing by-value is more efficient for small objects.) Unfortunately, optimized_prototype doesn't help one understand how this technique applies to register_function(). As you can now see, I think you should develop register_function() as you go along so the reader can see the reason for each aspect for which Boost.FunctionTypes can offer help.
When taking the address of an overloaded function or function template, the type of the function must be told to the compiler.
This part seems abrubtly different from the preceding text and examples. Does it fit with register_function() somehow or is it unrelated? If the latter, might I suggest that you delineate that separation? IOW, develop register_function() as far as you can using Boost.FunctionTypes facilities. When that example runs dry, move on to a new section and discuss the other facilities of the library with new examples. "Must be told to the compiler" is awkward at best. ...you must give the function's type to the compiler.
Boost.FunctionTypes can help automating it.
Fortunately, Boost.FunctionTypes can help to automate those cases:
The above metafunction can be used to create a situation similar to the third trivial example above in a nondeduced context of a function template like the following.
function_pointer_helper can now be used to simplify <something>.... "The third trivial example above in a nondeduced context of a function template" is practically useless. One has to work so hard to grok that phrase that one is unlikely to do it, so the example isn't likely to be of much value. What would be useful is to show exactly how to solve the std::for_each example. Don't leave more than necessary as an exercise for the reader. This is the introduction and you want to show how your library is actually used to solve real problems. feed_tuple_to_function references "Fusion" tuples. I presume those are part of the project under development for Boost that has yet to be accepted (so far as I recall). Why introduce what is likely to be foreign to many readers in your introduction?
Assuming these delcarations;
s/delcarations;/declarations/
Note that this technique is generally not well-suited to serve as an interface for generic facilities because it has many limitations, such as requiring a known result type and the exact parameter types (rather than types for possible arguments) and because feed_tuple_to_function cannot be overloaded.
After looking at the example and reading that text, I'm left to wonder what value the example offers. Is it something a person needs to do with any regularity (something I'd expect from a library introduction)? I'll have a look at http://neoscientists.org/~tschwinger/bft/boost_functiontypes/tag_types.html later. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart wrote:
From: Tobias Schwinger <tschwinger@neoscientists.org>
Documentation preview (includes three sections):
http://tinyurl.com/dg68y (not yet hyperlinked)
________________________________
Overview
Boost.FunctionTypes provides functionality to classify, decompose and synthesize function types and other compound types such as
^^^ ^^^ A prime example of why one really should always use the extra comma in a series. There can be no confusion when you do so.
...classify, decompose, and synthesize function types and other....
OK.
pointer-, reference- and pointer to member function types.
I don't get what "pointer-" and "reference-" are supposed to be joined with to make that phrase work. There are function pointer types and function reference types, but there are no "pointer-function types" or "reference-function types."
OK.
I'm assuming you meant this:
...types such as function pointer, function reference, and member function pointer types.
This means in other words to
This means you can
> * test whether a type is a specific callable builtin type,
...specific, callable, built-in type;
Note the trailing semicolon. Since some items in your list have commas, you need to use semicolons to separate the list items.
For all of them or just for the one with the commas?
Note also that "builtin" should be "built-in."
> * inspect function properties such as arity, kind, result- and parameter types, and
You haven't defined "kind," so it's not helpful here.
Right. It's an artefact.
What's "result-" supposed to connect to?
'types', however it seems English lacks this feature to enumerate compound words with a common ending ;-).
* inspect function properties such as arity, result type, parameter types, etc.; and
> * create callable builtin types from specified function properties.
...callable, built-in types....
OK.
it specializes in the manifold properties of callable builtin types.
As someone else wrote, "manifold properties" is almost inscrutable to me. While the usage is correct, the word is rarely used as an adjective.
Ahh! Now I fully understand what's wrong with this sentence!
s/builtin/built-in/
it specializes in the many properties of callable built-in types.
How about ... specializes in callable, built-in types. ??
_____________________________________
Introduction
About 300 overloads are needed for three different calling conventions and a maximum arity of 10. This calculation is
You haven't mentioned "calling conventions" before this. Shouldn't that be in the table?
It /is/ there. Did you perhaps overlook it in the table?
simplified and more irregular in reality.
s/and more/and is more/
OK.
* it can lead to a noticable slowdown,
* can be slower,
Slower than what?
(If not, fix the spelling of "noticeable.")
OK. I'll go with this one.
This is why Boost.FunctionTypes factors it out and allows
^^ Missing antecendent.
OK.
client code to arbitrarily classify and decompose any of the type's multi-faceted properties:
Boost.FunctionTypes addresses those disadvantages and allows your code to arbitrarily classify and decompose any of a function type's properties. The example becomes much simpler as the function template's template argument list and formal parameter type are reduced to "T":
The beginning is good. It's still too lengthy for my taste. Btw: simpler than what?
It can be desirable to transform callable built-in types. This
In other situations, you may need to transform from one callable built-in type to another.
I try to avoid 2nd person singular except for "please note blocks." Another situation is to ... Isn't that "from one to another"-thing implied by "tranform?"
is especially useful together with Boost.Function. The next example shows specializing boost::function to store an arbitrary callable scalar f of type F.
This example illustrates how to specialize boost::function to store an arbitrary, callable scalar f of type F:
Nice!
The example for that should really build upon the previous example:
template<typename F> void facility::register_function(F f) { boost::function<typename function_type<F>::type> wrapped = f; // call wrapped as appropriate }
It's intentional because it makes little sense in this context: You'ld usually want to do declare the boost::function at class scope (of a different class). More details on this issue can be found below.
An opportunity for optimization is to transform the signature changing by-value parameters to use constant references to avoid duplicate copy-construction when the boost::function object's parentheses operator is called (the fact that adding a reference can be inefficient for small sized objects is ignored for the sake of simplicity here).
Too long and missing at least a comma. It also doesn't guide the reader enough.
A common optimization, when forwarding parameters from one function to another, is to transform by-value parameters to references to const. This avoids creating superfluous copies when one function calls another.
Great!
In our example, if register_function() takes the argument types from its template argument F and uses them to declare the boost::function object f. If F includes by-value parameters, then register_function() will create superfluous copies of its arguments when calling f. Ideally, we want f to take its arguments by reference to const to avoid those copies. (For simplicity's sake, we ignore the fact that passing by-value is more efficient for small objects.)
Unfortunately, optimized_prototype doesn't help one understand how this technique applies to register_function().
OK. I had an invocation for this metafunction in there once... Seems it accidently got cut away ;-(.
As you can now see, I think you should develop register_function() as you go along so the reader can see the reason for each aspect for which Boost.FunctionTypes can offer help.
As stated above it's not that easy and would require more infrastructure around the examples. Previous example: template<typename T> void facility::register_function(T a) { < // [...] <-- use Boost.FunctionTypes on T
BOOST_MPL_ASSERT_MSG(is_callable_scalar<T>::value ,NO_CALLABLE_SCALAR_TYPE, (T)); this->callback = action<T>(a); // <-- uses Boost.FunctionTypes on T }
Then: template<typename F> class action { boost::function<typename function_type<F>::type> wrapped; action(F f) : wrapped(f) // ... }; Well, what I don't like about it (besides that there's more infrastructure around the actual thing) is that both are not necessarily the same case. I'm not feeling too strong about it, though (at least when there are headlines for every use case).
When taking the address of an overloaded function or function template, the type of the function must be told to the compiler.
This part seems abrubtly different from the preceding text and examples. Does it fit with register_function() somehow or is it unrelated?
Actually, all three are different.
If the latter, might I suggest that you delineate that separation?
I'ld have to add a headline for all of them (I wanted to do so but failed finding good titles so I left it out, for now).
IOW, develop register_function() as far as you can using Boost.FunctionTypes facilities. When that example runs dry, move on to a new section and discuss the other facilities of the library with new examples.
"Must be told to the compiler" is awkward at best.
...you must give the function's type to the compiler.
OK.
Boost.FunctionTypes can help automating it.
Fortunately, Boost.FunctionTypes can help to automate those cases:
Not sure about the "fortunately" -- the rest of it is bought.
The above metafunction can be used to create a situation similar to the third trivial example above in a nondeduced context of a function template like the following.
function_pointer_helper can now be used to simplify <something>....
Good.
"The third trivial example above in a nondeduced context of a function template" is practically useless. One has to work so hard to grok that phrase that one is unlikely to do it, so the example isn't likely to be of much value.
What would be useful is to show exactly how to solve the std::for_each example.
The problem is that you won't need the library for the std::for_each example.
Don't leave more than necessary as an exercise for the reader. This is the introduction and you want to show how your library is actually used to solve real problems.
feed_tuple_to_function references "Fusion" tuples. I presume those are part of the project under development for Boost that has yet to be accepted (so far as I recall). Why introduce what is likely to be foreign to many readers in your introduction?
It's a sub library of Boost.Spirit since Boost 1.31 (Fusion as a stand-alone library has yet to accepted, though). You don't have to be too familiar with Fusion to understand what's happening here.
Assuming these delcarations;
s/delcarations;/declarations/
Note that this technique is generally not well-suited to serve as an interface for generic facilities because it has many limitations, such as requiring a known result type and the exact parameter types (rather than types for possible arguments) and because feed_tuple_to_function cannot be overloaded.
After looking at the example and reading that text, I'm left to wonder what value the example offers.
Not everything has to be entirely generic to make sense and not every technique out there is for creating interfaces of generic libraries...
Is it something a person needs to do with any regularity (something I'd expect from a library introduction)?
There's not much regularity in the exact case shown by the example. However overload selection (the principle behind the example) is an important use case and should be shown here. Testing whether a class type contains a particular member function (based on SFINAE and sizeof), is a more regular case but less obvious and depends on tricky techniques that would require off-scope explanation. Thank you very much, Tobias

From: Tobias Schwinger <tschwinger@neoscientists.org>
Rob Stewart wrote:
From: Tobias Schwinger <tschwinger@neoscientists.org>
> * test whether a type is a specific callable builtin type,
...specific, callable, built-in type;
Note the trailing semicolon. Since some items in your list have commas, you need to use semicolons to separate the list items.
For all of them or just for the one with the commas?
All of them.
s/builtin/built-in/
it specializes in the many properties of callable built-in types.
How about
... specializes in callable, built-in types.
??
Right, that should have been: ...specializes in the properties of callable, built-in types.
About 300 overloads are needed for three different calling conventions and a maximum arity of 10. This calculation is
You haven't mentioned "calling conventions" before this. Shouldn't that be in the table?
It /is/ there. Did you perhaps overlook it in the table?
Doh!
* it can lead to a noticable slowdown,
* can be slower,
Slower than what?
I can ask the same thing for your version. We could s/be/execute/ to clarify, but I'm not sure it is needed.
client code to arbitrarily classify and decompose any of the type's multi-faceted properties:
Boost.FunctionTypes addresses those disadvantages and allows your code to arbitrarily classify and decompose any of a function type's properties. The example becomes much simpler as the function template's template argument list and formal parameter type are reduced to "T":
The beginning is good. It's still too lengthy for my taste. Btw: simpler than what?
Than the previous version of register_types.
It can be desirable to transform callable built-in types. This
In other situations, you may need to transform from one callable built-in type to another.
I try to avoid 2nd person singular except for "please note blocks."
Another situation is to ...
I was trying to convey that the idea that the reader could well encounter the situation. I was trying to make it less theoretical.
Isn't that "from one to another"-thing implied by "tranform?"
Yes, in part, but that phrase adds clarity for me. There are situations that require transforming one callable built-in type into another.
The example for that should really build upon the previous example:
template<typename F> void facility::register_function(F f) { boost::function<typename function_type<F>::type> wrapped = f; // call wrapped as appropriate }
It's intentional because it makes little sense in this context: You'ld usually want to do declare the boost::function at class scope (of a different class).
So use a footnote to explain the shortcut taken for brevity's sake.
More details on this issue can be found below.
OK.
As you can now see, I think you should develop register_function() as you go along so the reader can see the reason for each aspect for which Boost.FunctionTypes can offer help.
As stated above it's not that easy and would require more infrastructure around the examples.
Previous example:
template<typename T> void facility::register_function(T a) { < // [...] <-- use Boost.FunctionTypes on T
BOOST_MPL_ASSERT_MSG(is_callable_scalar<T>::value ,NO_CALLABLE_SCALAR_TYPE, (T)); this->callback = action<T>(a); // <-- uses Boost.FunctionTypes on T }
Then:
template<typename F> class action { boost::function<typename function_type<F>::type> wrapped;
action(F f) : wrapped(f) // ... };
Well, what I don't like about it (besides that there's more infrastructure around the actual thing) is that both are not necessarily the same case. I'm not feeling too strong about it, though (at least when there are headlines for every use case).
You can transform the free function into a member function when you reach that point. If the function has the same name and effective arguments after the transformation, it should make sense and will still help to tell the story.
When taking the address of an overloaded function or function template, the type of the function must be told to the compiler.
This part seems abrubtly different from the preceding text and examples. Does it fit with register_function() somehow or is it unrelated?
Actually, all three are different.
If the latter, might I suggest that you delineate that separation?
I'ld have to add a headline for all of them (I wanted to do so but failed finding good titles so I left it out, for now).
If there's a way to work that in with the same example, it would help the reader. Otherwise, it is harder to follow.
Boost.FunctionTypes can help automating it.
Fortunately, Boost.FunctionTypes can help to automate those cases:
Not sure about the "fortunately" -- the rest of it is bought.
OK, omit "fortunately."
"The third trivial example above in a nondeduced context of a function template" is practically useless. One has to work so hard to grok that phrase that one is unlikely to do it, so the example isn't likely to be of much value.
What would be useful is to show exactly how to solve the std::for_each example.
The problem is that you won't need the library for the std::for_each example.
Then why is it an example of a problem in your introduction? Pick one of the other examples and show exactly how to solve it. What you did does not solve one of the examples you gave.
Don't leave more than necessary as an exercise for the reader. This is the introduction and you want to show how your library is actually used to solve real problems.
feed_tuple_to_function references "Fusion" tuples. I presume those are part of the project under development for Boost that has yet to be accepted (so far as I recall). Why introduce what is likely to be foreign to many readers in your introduction?
It's a sub library of Boost.Spirit since Boost 1.31 (Fusion as a stand-alone library has yet to accepted, though).
So if the reader hasn't used Boost.Spirit, the reader will probably not know about Fusion.
You don't have to be too familiar with Fusion to understand what's happening here.
Nevertheless, it is something unfamiliar introduced without providing help in understanding your library.
Note that this technique is generally not well-suited to serve as an interface for generic facilities because it has many limitations, such as requiring a known result type and the exact parameter types (rather than types for possible arguments) and because feed_tuple_to_function cannot be overloaded.
After looking at the example and reading that text, I'm left to wonder what value the example offers.
Not everything has to be entirely generic to make sense and not every technique out there is for creating interfaces of generic libraries...
I don't think that note is helpful in an introduction then. It leads the reader to question why you presented the example. You can reserve such caveats for a more advanced section of the documentation.
Is it something a person needs to do with any regularity (something I'd expect from a library introduction)?
There's not much regularity in the exact case shown by the example. However overload selection (the principle behind the example) is an important use case and should be shown here.
OK, I see what I didn't like about the text now. Starting with "Assuming these declarations," you should rework the text (not the note) like this: Boost.FunctionTypes also helps when selecting from among overloaded functions. Assuming these declarations ... it is possible to select the first overload of overloaded_function and the function_template<int,long> specialization when using a tuple with int and long in it: ... (This may be where you have to use Fusion tuples, but if you can use MPL instead, I think that would be wise.) -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

From: Tobias Schwinger <tschwinger@neoscientists.org>
Documentation preview (includes three sections):
http://tinyurl.com/dg68y (not yet hyperlinked)
_________________________ Tag Types
The following code creates the type int __fastcall (int...).
function_type<mpl::vector<int,int>, tag<variadic,fastcall> >::type ^^^^^^^ I suggest changing either the return type or the parameter type so you don't get "int,int" to make things clearer.
Default values are selected for properties not specified by the tag. The next example creates the type of a function (variadic in this case) of the default calling convention. int(int...).
Something got munged here. Here's another try: The following expression produces a function type for variadic functions with a first parameter of type int which return an int. Since a calling convention isn't specified, the default calling convention is used.
function_type<mpl::vector<int,int>, variadic>::type
^^^^^^^ As before, I suggest changing the return or parameter type. Other than that, I think the page is very good. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart <stewart@sig.com> writes:
Something got munged here. Here's another try:
The following expression produces a function type for variadic functions with a first parameter of type int which return an int. Since a calling convention isn't specified, the default calling convention is used.
I suggest: The following expression produces a function type for variadic functions that return an int and have a first parameter of type int.
function_type<mpl::vector<int,int>, variadic>::type
^^^^^^^ As before, I suggest changing the return or parameter type.
That's a good idea. -- Dave Abrahams Boost Consulting www.boost-consulting.com

Rob Stewart wrote:
From: Tobias Schwinger <tschwinger@neoscientists.org>
Documentation preview (includes three sections):
http://tinyurl.com/dg68y (not yet hyperlinked)
_________________________ Tag Types
The following code creates the type int __fastcall (int...).
function_type<mpl::vector<int,int>, tag<variadic,fastcall> >::type
^^^^^^^ I suggest changing either the return type or the parameter type so you don't get "int,int" to make things clearer.
Good point!
Default values are selected for properties not specified by the tag. The next example creates the type of a function (variadic in this case) of the default calling convention. int(int...).
Something got munged here. Here's another try:
The following expression produces a function type for variadic functions with a first parameter of type int which return an int. Since a calling convention isn't specified, the default calling convention is used.
OK. But why add so much talk about the component types here? The following expression produces a function type for variadic function. Since a calling convention isn't specified, the default calling convention is used. function_type<mpl::vector<void,int>, variadic>::type // is void (int...) Should be enough, right?
function_type<mpl::vector<int,int>, variadic>::type
^^^^^^^ As before, I suggest changing the return or parameter type.
Other than that, I think the page is very good.
Thanks, Tobias

From: Tobias Schwinger <tschwinger@neoscientists.org>
Rob Stewart wrote:
From: Tobias Schwinger <tschwinger@neoscientists.org>
Default values are selected for properties not specified by the tag. The next example creates the type of a function (variadic in this case) of the default calling convention. int(int...).
Something got munged here. Here's another try:
The following expression produces a function type for variadic functions with a first parameter of type int which return an int. Since a calling convention isn't specified, the default calling convention is used.
OK. But why add so much talk about the component types here?
The following expression produces a function type for variadic function. Since a calling convention isn't specified, the default calling convention is used.
function_type<mpl::vector<void,int>, variadic>::type // is void (int...)
Should be enough, right?
Yes, that's fine. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;
participants (5)
-
Angus Leeming
-
David Abrahams
-
John Maddock
-
Rob Stewart
-
Tobias Schwinger