Boost logo

Boost :

From: shunsuke (pstade.mb_at_[hidden])
Date: 2008-04-03 13:22:29


Giovanni Piero Deretta wrote:
> On Thu, Apr 3, 2008 at 1:53 AM, shunsuke <pstade.mb_at_[hidden]> 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

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