
Giovanni Piero Deretta wrote:
On Thu, Apr 3, 2008 at 1:53 AM, shunsuke <pstade.mb@gmail.com> wrote:
Giovanni Piero Deretta wrote:
You expect something like this?:
static_result_of<T_curry2(F)>::type c = BOOST_EGG_CURRY2({}); // static
Can't you use boost::result_of here? (or return_of)
As I mentioned, result_of needs to know whether or not an argument is lvalue or rvalue. result_of is standardized, so that I don't like to violate the law.
I still do not get it though. Could you show me exactly where you think the problem is?
boost::result_of<F(T)>::type
will return the type of the result of 'F()(T());' right? Once you know the type, and if you are sure that the type is an aggregate, doing 'boost::result_of<F(T)>::type c = {};' should always be legal. What I'm missing?
No. I'm just thinking twice about result_of without function-calls. For http://tinyurl.com/yuumdv, I have to admit such result_of, after all.
Also, as Eric stated in Proto doc, result_of compiles slow.
Ok. Is your static_result_of faster? And if so, couldn't you just port your improvements to the basic result_of? (or there are differences that allow you to take shortcuts?).
I think of specializing boost::result_of directly: template<class F> struct result_of<T_curry2(F)> : egg::result_of_curry2<typename remove_cv_ref<F>::type> { }; Though Eric states that even remove_cv_ref makes compiling slower, it's worth a try.
Also, do you have a plan for allowing complex statically initialized expressions in header files without ODR violations?
Though BOOST_EGG_CONST does nothing for now, it has the potential to work around the ODR violation. But I hesitate to say "Any function definition requires a macro!".
Only if you want to put them in an header file. Just to clarify, what I do is this:
template<typename Aggregate> struct instance_of { static Aggregate instance; };
template<typename Aggregate> Aggregate instance_of::instance = {};
Then I use it like this:
// in an header const fold_t& fold = instance_of<fold_t>::instance;
I usual hide the last line in a macro:
INSTANCE_OF(fold_t, fold);
Can EGG_CONST do something like this?
Yes. EGG_CONST was called POD_CONSTANT: http://tinyurl.com/2bdk5c The static_initialization is really tested by libs/test/static_initialization.cpp. One day, that test was failed around egg::indirect. POD_CONSTANT((int), v) = 0; // gcc can static-initialize v. msvc can't (without optimizer). POD_CONSTANT((int *), p) = &v; // Doh, gcc CAN'T static-initialize p. msvc can't of course. Thus, EGG_CONST has been turned into just `const`. I guess the ODR violation workaround will never be turned on.
Anyway, I want to follow the Boost.Proto way.
boost::result_of<T_curry2(F const &)>::type c = curry2(f); // dynamic
or egg::return_of if you want recursive evaluation.
I'm not sure return_of is portable under msvc. That trivial example( http://tinyurl.com/yuumdv ) actually doesn't compile. :-(
Ah, ok. I also had problems with gcc.3.3 not digesting complex function type expressions. May be this syntax would be better:
return_of<function_name, Arg1, Arg2, Arg3>::type
and you can compose it like this:
return_of<function1, return_of<function2, Arg1_1>, Arg2_1>::type
This is more mpl friendly (result_of is a pain to use with mpl).
Ok. I'm going to rewrite return_of.
stateless_result_of<T_curry2(F)>::type c = BOOST_EGG_STATELESS(); // for stateless one.
Why not:
expression<T_curry2(F)> c = { /*just this please :) */ }; // note the missing ::type
It seems impossible to remove ::type, because `expression` can't use inheritance so that it can be a POD.
I do not think that podness is a problem, is just that it seems that the brace initializer can't be used with inheritance. But may be if the wrapped function object *really* stateless, you need no inheritance. You could just instantiate it directly in operator().
Egg has the ForwardingStrategies. For example, the perfect forwarding must be implemented using egg::function<L, by_perfect>. Otherwise, yet another 2^N operator()s would be needed. Regards, -- Shunsuke Sogame