[function] generalization of std::plus and std::multiplies with more than one argument type

Does Boost have a generalization of std::plus and std::multiplies (std_function.hpp)? The standard defines this with only one template parameter template <class _Tp> struct multiplies : public binary_function<_Tp, _Tp, _Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } }; but I need something more general, where the types are different multiplies<type1, type2, type2> (assuming that the result has the type of the rhs. of course I could just define template <class _Tp1, class _Tp2, class Tp3> struct multiplies : public binary_function<_Tp1, _Tp2, _Tp3> { _Tp3 operator()(const _Tp1& __x, const _Tp2& __y) const { return __x * __y; } }; but I don't want to clutter my code with these pieces of basic code, specially if something like this is already part of other facilities in Boost. (Or even better, it would be nice if multiples<type3(type1, type2)> were defined, maybe I am asking to much sugar). I need this specific kind of multiply<3 args> in order to provide a default multiplication in the template parameters of vector space class, i.e. unless something is explicitly defined it tries to use * to implement scalar (pre)multiplication. (multiply<3 args> is the only reasonable default I can think of). Thanks, Alfredo

alfC wrote:
Does Boost have a generalization of std::plus and std::multiplies (std_function.hpp)?
How about the boost::lambda arithmetic operators, possibly in combination with ll_static_cast<Tp>, and -if necessary- put the result in the functor wrapper boost::function<Tp(const Tp&,const Tp&)>? You probably already know this but in my (non authoritative) opinion, this is as close a generalization as can be.

On 08.10.2009, at 17:27, er wrote:
alfC wrote:
Does Boost have a generalization of std::plus and std::multiplies (std_function.hpp)?
How about the boost::lambda arithmetic operators, possibly in combination with ll_static_cast<Tp>, and -if necessary- put the result in the functor wrapper boost::function<Tp(const Tp&,const Tp&)
?
You probably already know this but in my (non authoritative) opinion, this is as close a generalization as can be.
I had such a class in our libraries, but threw it out and replaced it with lambda expressions Matthias

thank you er and Mathias for your answers,
alfC wrote:
Does Boost have a generalization of std::plus and std::multiplies (std_function.hpp)?
How about the boost::lambda arithmetic operators, possibly in combination with ll_static_cast<Tp>, and -if necessary- put the result in the functor wrapper boost::function<Tp(const Tp&,const Tp&)
?
what is "ll_static_cast<Tp>"? after that part I got lost.
I had such a class in our libraries, but threw it out and replaced it with lambda expressions
but I need this generalization of multiplies as one of the default parameter of a template, how would you pass a lambda expression as template parameter? The reason I returned to my post is that today I found boost/mpl/ plus.hpp and boost/mpl/multiplies.hpp which seem to answer the first part of my question (although not the syntactic sugar part). Thank you, Alfredo

alfa wrote:
but I need this generalization of multiplies as one of the default parameter of a template, how would you pass a lambda expression as template parameter?
As a part of my workj on Boost.SIMD, i have a generlized fucntor with result_of protocol support and tag-dispatching. Basically : functor<plus>()(x,y) return the sum of x and y for the correct semantic of + for the type of x and y. result_of<functor<plus>(X,Y)>::type returns it result type. Is that smthg like that you need ?

As a part of my workj on Boost.SIMD, i have a generlized fucntor with result_of protocol support and tag-dispatching.
thank you, where I can find Boost.SIMD, is functor defined there?
Basically :
functor<plus>()(x,y)
return the sum of x and y for the correct semantic of + for the type of x and y.
is this "plus" the same as "std::plus"? If so how can x, y be of different type?
result_of<functor<plus>(X,Y)>::type returns it result type.
Is that smthg like that you need ?
seems very similar to what I am looking for. I will know after knowning more details. Thank you, Alfredo

alfC wrote:
thank you, where I can find Boost.SIMD, is functor defined there? Boost.SIMD is currently under work and will be released to the vault "soon"
is this "plus" the same as "std::plus"? If so how can x, y be of different type?
no, this plus is a tag defined by the library. x and y are from different type and i use a tag dispatching method to discriminate the actual semantic of plus to use. Basically, I scan the argument list and try to find non trivial types, if i do i ask for a specific properties called tag_of on those types and select the implementation to use to perform the operation. Currently we support arithmetic types and SIMD types but we provide an extension mecanism so you can define your own type set and give them proper implementation (for ex., complex number, matrix etc). All those variation are called by the same functor call anyway, making it a pure generic tag-dispatched computation facility.

AMDG alfC wrote:
The reason I returned to my post is that today I found boost/mpl/ plus.hpp and boost/mpl/multiplies.hpp which seem to answer the first part of my question (although not the syntactic sugar part).
mpl::plus and mpl::multiplies are not function objects. You can't use them with int, for example. They are metafunctions that mainly work with MPL Integral Constant Wrappers: BOOST_MPL_ASSERT((boost::mpl::equal_to< boost::mpl::plus<boost::mpl::int_<1>, boost::mpl::int_<2> >, boost::mpl::int_<3> >)); In Christ, Steven Watanabe

On Oct 16, 8:52 am, Steven Watanabe <watanab...@gmail.com> wrote:
mpl::plus and mpl::multiplies are not function objects. You can't use them with int, for example. They are metafunctions that mainly work with MPL Integral Constant Wrappers:
I see, I got confused because in the source (which is very difficult to read with all the defines, there is a point where you "#define AUX778076_OP_TOKEN +" so I though that it really implemented a functor. But it seems that the "token" is used only for the compile- time constants in the code after all. Thank you, Alfredo

alfC wrote:
thank you er and Mathias for your answers,
alfC wrote:
Does Boost have a generalization of std::plus and std::multiplies (std_function.hpp)? How about the boost::lambda arithmetic operators, possibly in combination with ll_static_cast<Tp>, and -if necessary- put the result in the functor wrapper boost::function<Tp(const Tp&,const Tp&) ?
what is "ll_static_cast<Tp>"? after that part I got lost.
the cast was in mind to allow for an argument that is convertible to but not necessarily equal to Tp.
but I need this generalization of multiplies as one of the default parameter of a template, how would you pass a lambda expression as template parameter?
Since you insist on a template parameter, template<typename Tp,template<typename> class G = default_factory> struct my_class{ typedef function<Tp(const Tp&,const Tp&)> F; my_class() : f(G<Tp>::create()){} F f; }; template<typename Tp> struct default_factory{ typedef BOOST_TYPEOF( lambda::_1 * lambda::_2 ) result_; static result_ create(){ return lambda::_1 * lambda::_2; } }; I did not even try to compile it, just an idea.
The reason I returned to my post is that today I found boost/mpl/ plus.hpp and boost/mpl/multiplies.hpp which seem to answer the first part of my question (although not the syntactic sugar part).
Thank you, Alfredo
participants (5)
-
alfC
-
er
-
Joel Falcou
-
Matthias Troyer
-
Steven Watanabe