
On Thu, May 1, 2008 at 3:00 PM, David Abrahams <dave@boost-consulting.com> wrote:
on Wed Apr 30 2008, "Daniel Walker" <daniel.j.walker-AT-gmail.com> wrote:
Aha! That just made me realize that I didn't fully understand what Dave was getting at yesterday. call() uses call-by-reference, and since boost::result_of<> treats all references as function references, you have to somehow decompose the reference before hand to determine what to pass to result_of<> so that it will do the right thing. OK. Then the snippet I sent yesterday will work for function references but not references to function objects. Still, I think the best thing to do in this case is to make call() accept only first-class function objects by value...
You're basically solving the problem by declaring it illegal. This issue comes up because I *want* to handle all callable types, and I expect to be able to use result_of to do it.
I only meant to offer a solution for the problem of passing around functions. I think result_of does handle all callable types, though the present TR1 heuristic version isn't perfect. I believe the larger problem is not how to get the return type from arbitrary callable objects but how to pass callable objects as arguments to other funtions. Isn't the simplest solution to adopt a functional programming style, which C++ allows, by treating functions as first-class objects? Actually, in functional programming languages I believe it's fairly common for all functions to be call-by-value when they are defined (I think this is the case in Lisp), though they may be invoked with references according to the environment at the call-site (similar to using ref() and cref() in C++). Obviously, C++ supports multiple programming styles, it has second-class functions, which don't act like values, and all of this is a good thing. I'm not saying that should change or be illegal. I'm just saying that a simple way to use second-class functions in a functional programming paradigm is to promote them to first-class. And a simple solution for resolving call-by-reference conflicts is to follow the example of other functional programming languages (and the C++ standard library, come to think of it), and differ the decision as to whether the functions are called by value or reference until the call site (via reference_wrapper<>). Actually, it may be possible to formalize these constraints in a set of concepts; then rather than simply being stylistic or idiomatic, the compiler could enforce them. They would be souped-up versions of SGI STL's Functors.
especially since all the tools needed to treat built-in functions or references to function objects as values will be available in C++0x as soon as you #include <functional>.
Please, don't speak to me of what's coming in 0x, at least not in the context of result_of. Presumably everything is warm, light, and golden in that mystical year of the future, and we won't need result_of. ;-)
Yes, actually, that mystical year may be 1x as there are only 19 months left until 2010. ;-) Still, I find myself using -std=c++0x all the time now, and seeing this stuff work out-of-the-box makes C++0x feel a lot more real to me, at least with respect to the library. Daniel