[Boost-users] Functors and function_traits<>

瀏覽次數:5 次
跳到第一則未讀訊息

Hossein Haeri

未讀,
2004年12月27日 上午9:08:002004/12/27
收件者:boost...@lists.boost.org
Dear all,

Yep, again it's me, and it's agian
function_traits<>...

AFAIK, std::iterator_traits<> is one of the
counterparts of function_traits<>, not?

A sort of symmetry which iterator_traits<> has got is
that it can work for Iterators as well as plain
pointers.

This seems to be not the case for function_traits<>.
That is, you can pass a function type to it, but you
can't do that for a functor. Is that right?

If it is, a big drawback turns out to happen for
variations of the following which are not that few
common:

template <
typename ...,
...,
typename Function
>
struct Foo
{
typedef
typename
function_traits<Function>
::result_type result_type;

Foo (Function f) : f_(f) {}

//...
result_type operator () () {/*..*/}

Function f_;
};

This well works for sth like this:

double f(double) {/*...*/}
Foo<blah, ..., double (&) (double)> foo(f);

But it does not work with the following:

struct F
{
double operator () () {/*...*/}
};
Foo f;
Foo<blah, ..., F> foo(f);

Is this what it should be? Or am I missing anything?

In fact, the following code:

struct F
{
double operator () (double x) const {return f(x);}
};

typedef
boost::function_traits<F>::result_type result_type;

makes GCC 3.3.1 to give me an error like the previous
one. This is what it says:

Compiler: Default compiler
Building Makefile: "C:\Documents and
Settings\Hossein\My Documents\My
Programmes\Probability
I\Distributions\7.2.1\Makefile.win"
Executing make...
make.exe -f "C:\Documents and Settings\Hossein\My
Documents\My Programmes\Probability
I\Distributions\7.2.1\Makefile.win" all
g++.exe -D__DEBUG__ -c 7_2_1Main.cpp -o 7_2_1Main.o
-I"C:/Dev-Cpp/include/c++/3.3.1"
-I"C:/Dev-Cpp/include/c++/3.3.1/mingw32"
-I"C:/Dev-Cpp/include/c++/3.3.1/backward"
-I"C:/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include"
-I"C:/Dev-Cpp/include" -pg -g3

7_2_1Main.cpp: In instantiation of
`boost::function_traits<F>':
7_2_1Main.cpp:70: instantiated from
`inverse_variate_generator<main()::Engine,
main()::Distribution, F>'
7_2_1Main.cpp:106: instantiated from here
7_2_1Main.cpp:70: error: base class
`boost::detail::function_traits_helper<F*>'
has incomplete type
7_2_1Main.cpp: In instantiation of
`inverse_variate_generator<main()::Engine,
main()::Distribution, F>':
7_2_1Main.cpp:106: instantiated from here
7_2_1Main.cpp:70: error: no type named `result_type'
in `struct
boost::function_traits<F>'
7_2_1Main.cpp:76: error: no type named `result_type'
in `struct
boost::function_traits<F>'

7_2_1Main.cpp: In function `int main()':
7_2_1Main.cpp:113: error: no match for call to `(
inverse_variate_generator<main()::Engine,
main()::Distribution, F>) ()'
7_2_1Main.cpp:117: error: no match for call to `(
inverse_variate_generator<main()::Engine,
main()::Distribution, F>) ()'

make.exe: *** [7_2_1Main.o] Error 1

Execution terminated

What's wrong with it? Am I missing anything?

If I'm not missing anything, then what is the
work-around? I find myself right in expecting myself
to be able to write a functor (like Foo) which can
work equaly well with both function pointers and
functors, as like as how the Standard algorithms do.
Am I right? Or am I right? ;)

TIA,
--Hossein



__________________________________
Do you Yahoo!?
Take Yahoo! Mail with you! Get it on your mobile phone.
http://mobile.yahoo.com/maildemo
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users

David Abrahams

未讀,
2004年12月27日 下午1:39:422004/12/27
收件者:boost...@lists.boost.org
Hossein Haeri wrote:
> Dear all,
>
> Yep, again it's me, and it's agian
> function_traits<>...
>
> AFAIK, std::iterator_traits<> is one of the
> counterparts of function_traits<>, not?
>
> A sort of symmetry which iterator_traits<> has got is
> that it can work for Iterators as well as plain
> pointers.

That's the wrong way to think about it. It just works for iterators.
Plain pointers just happen to be iterators, by the *standard's
definition* of "iterator."

> This seems to be not the case for function_traits<>.
> That is, you can pass a function type to it, but you
> can't do that for a functor. Is that right?

That's because function object types (what you're calling functors) are
not functions by the standard's definition of "function."

> If it is, a big drawback turns out to happen for
> variations of the following which are not that few
> common:
>
> template <
> typename ...,
> ...,
> typename Function
> >
> struct Foo
> {
> typedef
> typename
> function_traits<Function>
> ::result_type result_type;
>
> Foo (Function f) : f_(f) {}
>
> //...
> result_type operator () () {/*..*/}
>
> Function f_;
> };

It doesn't work because there's no way to code it in general. First of
all there's no universal standard for a way to get the result type of a
function object. Accessing a nested result_type sometimes works, but
then, sometimes the operator() is overloaded, or even templated.

You might look at boost::result_of for a more general solution.

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

Hossein Haeri

未讀,
2004年12月28日 清晨5:46:022004/12/28
收件者:boost...@lists.boost.org
Dave,

> > AFAIK, std::iterator_traits<> is one of the
> > counterparts of function_traits<>, not?
> >
> > A sort of symmetry which iterator_traits<> has got
> is
> > that it can work for Iterators as well as plain
> > pointers.
>
> That's the wrong way to think about it. It just
> works for iterators.
> Plain pointers just happen to be iterators, by the
> *standard's
> definition* of "iterator."

Smart Alec... ;) Alright I could be more specific
speaking like this:

"... it can work for Iterators which happen to be
classes as well as plain pointers."

Excused me? :)

> > This seems to be not the case for
> function_traits<>.
> > That is, you can pass a function type to it, but
> you
> > can't do that for a functor. Is that right?
>
> That's because function object types (what you're
> calling functors)

It's not me, AFAIK. That's another common name of
them. Isn't that?

> are
> not functions by the standard's definition of
> "function."

Sure.

> It doesn't work because there's no way to code it in
> general.

Eh, really? I'm begining to become upset when I see
Dave Abrahams -- of the biggest names in
Metaprogramming -- says that. :(

> First of
> all there's no universal standard for a way to get
> the result type of a
> function object. Accessing a nested result_type
> sometimes works, but
> then, sometimes the operator() is overloaded, or
> even templated.

Gush! Seems that you're right... :(

> You might look at boost::result_of for a more
> general solution.

Let me see. I'll be back afterwards... ;)

All of the Best,
--Hossein




__________________________________
Do you Yahoo!?
Yahoo! Mail - You care about security. So do we.
http://promotions.yahoo.com/new_mail

David Abrahams

未讀,
2004年12月28日 上午10:27:462004/12/28
收件者:boost...@lists.boost.org
Hossein Haeri wrote:
> Dave,
>
>> > AFAIK, std::iterator_traits<> is one of the
>> > counterparts of function_traits<>, not?
>> >
>> > A sort of symmetry which iterator_traits<> has got
>> is
>> > that it can work for Iterators as well as plain
>> > pointers.
>>
>> That's the wrong way to think about it. It just
>> works for iterators.
>> Plain pointers just happen to be iterators, by the
>> *standard's
>> definition* of "iterator."
>
> Smart Alec... ;) Alright I could be more specific
> speaking like this:
>
> "... it can work for Iterators which happen to be
> classes as well as plain pointers."
>
> Excused me? :)

I'm not just being pedantic. It's hard to explain why function_traits
is the way it is without making that distinction.

>> > This seems to be not the case for
>> function_traits<>.
>> > That is, you can pass a function type to it, but
>> you
>> > can't do that for a functor. Is that right?
>>
>> That's because function object types (what you're
>> calling functors)
>
> It's not me, AFAIK. That's another common name of
> them. Isn't that?

Yes, but it's frowned upon by many because it's a completely invented
meaning for a term that already had a well-established meaning in
mathematics and computing. If you read Stroustrup or almost any other
author who's also on the committee you'll see the term "function object"
and not "functor."

--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

Jeff Flinn

未讀,
2004年12月28日 上午10:48:202004/12/28
收件者:boost...@lists.boost.org
David Abrahams wrote:
> Hossein Haeri wrote:
>> Dave,
>>
...
>>>> can't do that for a functor. Is that right?
>>>
>>> That's because function object types (what you're
>>> calling functors)
>>
>> It's not me, AFAIK. That's another common name of
>> them. Isn't that?
>
> Yes, but it's frowned upon by many because it's a completely invented
> meaning for a term that already had a well-established meaning in
> mathematics and computing. If you read Stroustrup or almost any other
> author who's also on the committee you'll see the term "function
> object" and not "functor."

I had copied this description from a letter from the editor in either CUJ or
C++ Report some years back.

----------
Here's the low-down, to which any mathematician would attest:

A function is a transformation that maps an element to an element.
A functional is a transformation that maps a function to an element.
A functor is a transformation that maps a function to a function. (The truth
functions in propositional logic are also sometimes called functors.)

Simple, isn't it? We seem to use the first one correctly, but not the other
two. What people commonly call a functor (thanks to Dr. Coplien, shame!) is
what the C++ Standard calls a function object. It seems some people like to
use "functional" to mean the same thing. Shame again! A function object is
simply that, an instance of a class that behaves like a function by virtue
of its operator(). Some function objects, like bind2nd, do behave like
functors, in that they take a function object as input and return a function
object as output. Only these deserve the functor moniker, although you may
prefer "function object adaptor" (or is it spelled "adapter" :-), as denoted
in the C++ Standard.
----------

Jeff

Hossein Haeri

未讀,
2004年12月29日 清晨6:34:252004/12/29
收件者:boost...@lists.boost.org
I see. :)

All of the Best,
--Hossein



__________________________________
Do you Yahoo!?
Yahoo! Mail - Easier than ever with enhanced search. Learn more.
http://info.mail.yahoo.com/mail_250
回覆所有人
回覆作者
轉寄
0 則新訊息