C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Why function objects in <functional> doesn't use member temp

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Ganesh
Guest





PostPosted: Tue Jul 06, 2004 4:36 pm    Post subject: Why function objects in <functional> doesn't use member temp Reply with quote



The function objects (20.3) in <functional> like greater, negate are
templates. Hence we need to pass <T> explicitly while using them in
algorithms, as in the example 20.3.3:

[Example: If a C ++ program wants to have a by-element addition of two
vectors a and b containing double and put the result into a, it can
do:
transform(a.begin(), a.end(), b.begin(), a.begin(), plus<double>());
—end example]

Isn't that the use of function objects would have been simpler if
operator () were written as member templates?

For example, the call in previous example would look like:
transform(a.begin(), a.end(), a.begin(), negate());
Which is more convenient (atleast for me).

I don't see any significant technical difficulties for doing the same
(correct me if I am overlooking something obvious). For example, a
trivial implementation using member templates might be written as:

struct negate {
template <typename T> T operator() (const T &t) { return (-t);
}
};

-Ganesh

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Back to top
Alberto Barbati
Guest





PostPosted: Wed Jul 07, 2004 12:26 am    Post subject: Re: Why function objects in <functional> doesn't use member Reply with quote



Ganesh wrote:
Quote:

struct negate {
template <typename T> T operator() (const T &t) { return (-t);
}
};


In order to play nicely with binders, a functor need to be "adaptable"
according to old SGI terminology. In practice, this means that it has to
derive from std::unary_function<Arg, Result>. If you use member
templates, you simply cannot have that.

Alberto

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Terje Sletteb?
Guest





PostPosted: Thu Jul 15, 2004 10:37 pm    Post subject: Re: Why function objects in <functional> doesn't use member Reply with quote



[email]AlbertoBarbati (AT) libero (DOT) it[/email] (Alberto Barbati) wrote in message news:<OfHGc.39768$c_1.1252070 (AT) twister1 (DOT) libero.it>...

Just to add to my previous post, this line:

std::transform(begin(array),end(array),begin(array),bind1st(plus(),10);
// Add 10 to each element

can of course be written as:

std::transform(begin(array),end(array),begin(array),_1+10); // Add
10 to each element

given that I used Boost.Lambda (BLL) elsewhere in the example. :)

However, for functors, such as plus, when using BLL, you need to
specify the return type explicitly:

std::transform(begin(array),end(array),begin(array),bind<int>(plus(),_1,10));
// Add 10 to each element

Maybe it could be an idea to let Boost.Lambda use result_of?

Regards,

Terje

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Back to top
Terje Sletteb?
Guest





PostPosted: Fri Jul 16, 2004 4:55 am    Post subject: Re: Why function objects in <functional> doesn't use member Reply with quote

[email]AlbertoBarbati (AT) libero (DOT) it[/email] (Alberto Barbati) wrote in message news:<OfHGc.39768$c_1.1252070 (AT) twister1 (DOT) libero.it>...
Quote:
Ganesh wrote:

struct negate {
template <typename T> T operator() (const T &t) { return (-t);
}
};


In order to play nicely with binders, a functor need to be "adaptable"
according to old SGI terminology. In practice, this means that it has to
derive from std::unary_function<Arg, Result>. If you use member
templates, you simply cannot have that.

Hm, using the result_of proposal
([url]http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html)[/url],
you can actually create functors that don't need to be adaptable.

The following is a complete example (using the latest version of the
Boost CVS), which compiles and runs on g++ 3.2:

--- Start code ---

#include <iostream>
#include <algorithm>
#include <boost/collection_traits/begin.hpp>
#include <boost/collection_traits/end.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/utility/result_of.hpp>

using namespace boost;
using namespace boost::lambda;

// Teach it about the return type of the plus functor, using
// boost::result_of. For compilers supporting typeof, this
// isn't necessary, as result_of should then be able to deduce
// the type, itself.

struct plus;

namespace boost {

template<>
struct result_of<plus(int,int)> { typedef int type; }; // int+int =
int

} // namespace boost

// New version of plus

struct plus
{
template<class P1,class P2>
typename result_of<plus(P1,P2)>::type
operator()(const P1 &p1,const P2 &p2) const { return p1+p2; }
};

// New version of bind1st

template<class F,class P1>
struct binder1st
{
binder1st(const F &f,const P1 &p1) : f(f),p1(p1) {}

template<class P2>
typename result_of<F(P1,P2)>::type
operator()(const P2 &p2) const { return f(p1,p2); }

private:
F f;
P1 p1;
};

template<class F,class P1>
binder1st<F,P1> bind1st(const F &f,const P1 &p1) { return
binder1st<F,P1>(f,p1); }

int main()
{
int array[10];

int count=0;

std::generate(begin(array),end(array),++var(count)); // Fill array
with 1..10

std::transform(begin(array),end(array),begin(array),bind1st(plus(),10));
// Add 10 to each element

std::for_each(begin(array),end(array),std::cout << _1 << ' '); //
Print the array elements
}

--- End code ---

Output: "11 12 13 14 15 16 17 18 19 20"

Using typeof, the specialisation of result_of wouldn't be necessary.
However, trying to use g++'s typeof didn't work in this case, it
crashed, so I used an explicit specialisation, instead.

Regards,

Terje

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.