Topic: Functors for names
Author: jpalecek@web.de
Date: Thu, 5 Oct 2006 17:22:14 CST Raw View
Greg Herlihy napsal:
> jpalecek@web.de wrote:
> > Greg Herlihy napsal:
> > > jpalecek@web.de wrote:
> > > > Hello,
> > > >
> > > > shouldn't it be possible to create functors just for function _names_,
> > > > not function pointers?
> > > >
> > > > The problem is that you cannot do anything if you have to pass
> > > > eg. an overloaded function or templated function somewhere.
> > >
> > > It is possible to obtain a function pointer to an overloaded function
> > > with a cast or assignment to a function pointer variable of the desired
> > > type. For example, given an overloaded f() function:
> > >
> > > int f(int);
> > > double f(long);
> > > template <class T>
> > > T f(T);
> > >
> > > a program can obtain a function pointer to either of the first two
> > > overloads of f() like so:
> > >
> > > int (*fIntPtr)(int) = f;
> > > double (*fLongPtr)(long) = f;
> > >
> > Sorry, but this doesn't answer the question. If you looked at the
> > functor
> > I sketched, you'd see that it would do all these things at once. For
> > arguments of type int, it calls f(int), for argument of type Vector, it
> >
> > calls f(Vector). You could use it eg. as a visitor for boost::variant
> > (and
> > the need to specify exact type for the function pointer is just
> > annoying
> > and error-prone).
> >
> > Again, I didn't ask about function _pointers_.
>
> A function name is a function pointer in C++, so any implementation of
> a "NameFunctor" at the language level (as opposed to the preprocessing
> stage) will necessarily be dealing in function pointers as stand-ins
> for function names.
No, a function name is not a function pointer. If a function is a
template,
or overloaded, it is just nothing (because it has no type) until the
type
is resolved. However, you can't store a value like that. Therefore, any
solution can't use function pointers because you can't get them, and
it si unnecessary. The "overloaded function functors" don't have any
meaningful except for function call.
> I think that the implementation that would come the closest to the one
> described would employ a function pointer parameter to disambiguate the
> name at the point the function is called. Note that solution is not
> ideal: for a template function functor, the parameter types have to
> match the target function's signature exactly:
>
> template <class A, class B, class R>
> R NameFunctor(A a, B b, R (*pf)(A, B))
> {
> return (*pf)(a, b);
> }
>
> int f( double a, long b);
> short f( const char* a, int b);
>
> int main()
> {
> NameFunctor(1.0, 3L, f); // calls f(double, long)
> NameFunctor("test", 5, f); // calls f(const char *, int)
> }
This doesn't work for templates. Moreover, it is not a functor, and if
you
put it in an object, it wouldn't be of much use as a functor, because
if
you wanted to use it eg. in lambdas, you would have to bind it, but
you cannot because you cannot store the unresolved overloaded
function pointer in the bind functor.
Regards
Jiri Palecek
---
[ 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.comeaucomputing.com/csc/faq.html ]
Author: jpalecek@web.de
Date: Thu, 5 Oct 2006 18:33:43 CST Raw View
"Kristof Zelechovski" napsal:
> Uzytkownik "Greg Herlihy" <greghe@pacbell.net> napisal w wiadomosci
> news:1159804038.167990.18700@i42g2000cwa.googlegroups.com...
> > jpalecek@web.de wrote:
> >> Greg Herlihy napsal:
> >> > jpalecek@web.de wrote:
> >> > > Hello,
> >> > >
> >> > > shouldn't it be possible to create functors just for function
> >> > > _names_,
> >> > > not function pointers?
> >> > >
> >> > > The problem is that you cannot do anything if you have to pass
> >> > > eg. an overloaded function or templated function somewhere.
> >> >
> >> > It is possible to obtain a function pointer to an overloaded function
> >> > with a cast or assignment to a function pointer variable of the desired
> >> > type. For example, given an overloaded f() function:
> >> >
> >> > int f(int);
> >> > double f(long);
> >> > template <class T>
> >> > T f(T);
> >> >
> >> > a program can obtain a function pointer to either of the first two
> >> > overloads of f() like so:
> >> >
> >> > int (*fIntPtr)(int) = f;
> >> > double (*fLongPtr)(long) = f;
> >> >
> >> Sorry, but this doesn't answer the question. If you looked at the
> >> functor
> >> I sketched, you'd see that it would do all these things at once. For
> >> arguments of type int, it calls f(int), for argument of type Vector, it
> >>
> >> calls f(Vector). You could use it eg. as a visitor for boost::variant
> >> (and
> >> the need to specify exact type for the function pointer is just
> >> annoying
> >> and error-prone).
> >>
> >> Again, I didn't ask about function _pointers_.
> >
> > A function name is a function pointer in C++, so any implementation of
> > a "NameFunctor" at the language level (as opposed to the preprocessing
> > stage) will necessarily be dealing in function pointers as stand-ins
> > for function names.
> >
>
> I understand that the amendment would be to defer overload resolution to the
> point where the function is called or its address is taken. In particular,
Yes, but I would like more. I would like to store the "overloaded
function
pointer" to a variable and resolve the overloads during calls.
> overload resolution should not be performed when a template function is
> passed as a template parameter. I am for it and it was actually my idea
> some time ago. Suppose you want to find an upper bound of a value in a
> sequence of values of a different type. If the comparison does not use
> external reference data, you are normally able to pass a comparison
> predicate that compares an item to the value. However, this does not work
> for Visual C++ with iterator debugging because the Dinkumware implementation
> also wants to compare an item to an item in order to verify that the
> sequence is indeed monotonic. Therefore you overload your comparison
> function to be able to consider two items as well - only to find out that
> such a function cannot be passed to the template code without disambiguation
> at the place of instantiation, which is too early.
I didn't know about this use, but yes, this is sensible.
Regards
Jiri Palecek
---
[ 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.comeaucomputing.com/csc/faq.html ]
Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Mon, 2 Oct 2006 12:03:25 CST Raw View
jpalecek@web.de wrote:
> Greg Herlihy napsal:
> > jpalecek@web.de wrote:
> > > Hello,
> > >
> > > shouldn't it be possible to create functors just for function _names_,
> > > not function pointers?
> > >
> > > The problem is that you cannot do anything if you have to pass
> > > eg. an overloaded function or templated function somewhere.
> >
> > It is possible to obtain a function pointer to an overloaded function
> > with a cast or assignment to a function pointer variable of the desired
> > type. For example, given an overloaded f() function:
> >
> > int f(int);
> > double f(long);
> > template <class T>
> > T f(T);
> >
> > a program can obtain a function pointer to either of the first two
> > overloads of f() like so:
> >
> > int (*fIntPtr)(int) = f;
> > double (*fLongPtr)(long) = f;
> >
> Sorry, but this doesn't answer the question. If you looked at the
> functor
> I sketched, you'd see that it would do all these things at once. For
> arguments of type int, it calls f(int), for argument of type Vector, it
>
> calls f(Vector). You could use it eg. as a visitor for boost::variant
> (and
> the need to specify exact type for the function pointer is just
> annoying
> and error-prone).
>
> Again, I didn't ask about function _pointers_.
A function name is a function pointer in C++, so any implementation of
a "NameFunctor" at the language level (as opposed to the preprocessing
stage) will necessarily be dealing in function pointers as stand-ins
for function names.
I think that the implementation that would come the closest to the one
described would employ a function pointer parameter to disambiguate the
name at the point the function is called. Note that solution is not
ideal: for a template function functor, the parameter types have to
match the target function's signature exactly:
template <class A, class B, class R>
R NameFunctor(A a, B b, R (*pf)(A, B))
{
return (*pf)(a, b);
}
int f( double a, long b);
short f( const char* a, int b);
int main()
{
NameFunctor(1.0, 3L, f); // calls f(double, long)
NameFunctor("test", 5, f); // calls f(const char *, int)
}
Greg
---
[ 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.comeaucomputing.com/csc/faq.html ]
Author: giecrilj@stegny.2a.pl ("Kristof Zelechovski")
Date: Wed, 4 Oct 2006 15:03:33 GMT Raw View
Uzytkownik "Greg Herlihy" <greghe@pacbell.net> napisal w wiadomosci
news:1159804038.167990.18700@i42g2000cwa.googlegroups.com...
> jpalecek@web.de wrote:
>> Greg Herlihy napsal:
>> > jpalecek@web.de wrote:
>> > > Hello,
>> > >
>> > > shouldn't it be possible to create functors just for function
>> > > _names_,
>> > > not function pointers?
>> > >
>> > > The problem is that you cannot do anything if you have to pass
>> > > eg. an overloaded function or templated function somewhere.
>> >
>> > It is possible to obtain a function pointer to an overloaded function
>> > with a cast or assignment to a function pointer variable of the desired
>> > type. For example, given an overloaded f() function:
>> >
>> > int f(int);
>> > double f(long);
>> > template <class T>
>> > T f(T);
>> >
>> > a program can obtain a function pointer to either of the first two
>> > overloads of f() like so:
>> >
>> > int (*fIntPtr)(int) = f;
>> > double (*fLongPtr)(long) = f;
>> >
>> Sorry, but this doesn't answer the question. If you looked at the
>> functor
>> I sketched, you'd see that it would do all these things at once. For
>> arguments of type int, it calls f(int), for argument of type Vector, it
>>
>> calls f(Vector). You could use it eg. as a visitor for boost::variant
>> (and
>> the need to specify exact type for the function pointer is just
>> annoying
>> and error-prone).
>>
>> Again, I didn't ask about function _pointers_.
>
> A function name is a function pointer in C++, so any implementation of
> a "NameFunctor" at the language level (as opposed to the preprocessing
> stage) will necessarily be dealing in function pointers as stand-ins
> for function names.
>
I understand that the amendment would be to defer overload resolution to the
point where the function is called or its address is taken. In particular,
overload resolution should not be performed when a template function is
passed as a template parameter. I am for it and it was actually my idea
some time ago. Suppose you want to find an upper bound of a value in a
sequence of values of a different type. If the comparison does not use
external reference data, you are normally able to pass a comparison
predicate that compares an item to the value. However, this does not work
for Visual C++ with iterator debugging because the Dinkumware implementation
also wants to compare an item to an item in order to verify that the
sequence is indeed monotonic. Therefore you overload your comparison
function to be able to consider two items as well - only to find out that
such a function cannot be passed to the template code without disambiguation
at the place of instantiation, which is too early.
Chris
---
[ 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.comeaucomputing.com/csc/faq.html ]
Author: jpalecek@web.de
Date: Fri, 29 Sep 2006 18:19:44 CST Raw View
Hello,
shouldn't it be possible to create functors just for function _names_,
not function pointers?
The problem is that you cannot do anything if you have to pass
eg. an overloaded function or templated function somewhere.
You CAN create a functor for this, which will look like
struct nameFunctor
{
template <class A,class B> Ret operator()(A a,B b) {
return name(a,b);
}
... etc ...
}
but:
- this is tedious work (you have to do that for every name in your
program)
- I've not defined what "Ret" is, it's quite hard to figure out
<OT>
BTW: would something like
template <class A,class B,class Ret> Ret operator()(A a,B b,Ret
r=name(a,b)) {
return r;
}
work?
</OT>
I know this can (theoretically) be accomplished using the preprocessor,
but I think it would be much better to get such thing from the compiler
(as well as return type information for any expression).
Regards
Jiri Palecek
---
[ 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.comeaucomputing.com/csc/faq.html ]
Author: "harlyonester@gmail.com" <harlyonester@gmail.com>
Date: Sat, 30 Sep 2006 09:34:08 CST Raw View
jpalecek@web.de
> struct nameFunctor
> {
> template <class A,class B> Ret operator()(A a,B b) {
> return name(a,b);
> }
> ... etc ...
> }
>
> but:
> - this is tedious work (you have to do that for every name in your
> program)
> - I've not defined what "Ret" is, it's quite hard to figure out
>
> <OT>
> BTW: would something like
> template <class A,class B,class Ret> Ret operator()(A a,B b,Ret
> r=name(a,b)) {
> return r;
> }
>
> work?
> </OT>
>
your method like this "
> template <class A,class B,class Ret> Ret operator()(A a,B b,Ret
> r=name(a,b)) {
> return r;
> }
> "
is closing right..
If you modify tiny,It will work.
eg:
template<typename Ret>
struct nameFunctor
{
template <class A,class B> Ret operator()(A a,B b) {
return name(a,b);
}
... etc ...
}
Now you can use this struct like this:
nameFunctor<int> ,nameFunctor<string>,...etc
---
[ 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.comeaucomputing.com/csc/faq.html ]
Author: "Greg Herlihy" <greghe@pacbell.net>
Date: Sat, 30 Sep 2006 09:33:32 CST Raw View
jpalecek@web.de wrote:
> Hello,
>
> shouldn't it be possible to create functors just for function _names_,
> not function pointers?
>
> The problem is that you cannot do anything if you have to pass
> eg. an overloaded function or templated function somewhere.
It is possible to obtain a function pointer to an overloaded function
with a cast or assignment to a function pointer variable of the desired
type. For example, given an overloaded f() function:
int f(int);
double f(long);
template <class T>
T f(T);
a program can obtain a function pointer to either of the first two
overloads of f() like so:
int (*fIntPtr)(int) = f;
double (*fLongPtr)(long) = f;
The third f() overload is a function template; therefore it has no
address that could be passed as a function pointer. A program must
specify (or the compiler must be able to deduce in some way) which
specialization of f() the function pointer refers to. Since expressions
involving function pointers can be notoriously hard to decipher, it's
often a good idea to use typedefs as well:
typedef short (*FShortPtr)(short);
FShortPtr fp = &f<short>;
> You CAN create a functor for this, which will look like
>
> struct nameFunctor
> {
> template <class A,class B> Ret operator()(A a,B b) {
> return name(a,b);
> }
> ... etc ...
> }
The Standard library already has a routine that returns a function
object when passed a function pointer to a routine that accepts one or
two parameters: std::ptr_fun(). The std::tr1 library greatly expands
the Library's support for function objects by adding an entire function
class class template, std::tr1::function, and a result_of class
template to help deduce function return types. But as (hopefully) the
first of this answer was able to make clear, none of this library
support is needed to obtain a function pointer for any kind of
function.
Greg
---
[ 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.comeaucomputing.com/csc/faq.html ]
Author: jpalecek@web.de
Date: Mon, 2 Oct 2006 00:11:47 CST Raw View
harlyonester@gmail.com napsal:
> jpalecek@web.de:
> your method like this "
> > template <class A,class B,class Ret> Ret operator()(A a,B b,Ret
> > r=name(a,b)) {
> > return r;
> > }
> > "
> is closing right..
I'm sorry, I don't understand
>
> If you modify tiny,It will work.
> eg:
>
> template<typename Ret>
> struct nameFunctor
> {
> template <class A,class B> Ret operator()(A a,B b) {
> return name(a,b);
> }
> ... etc ...
> }
>
> Now you can use this struct like this:
> nameFunctor<int> ,nameFunctor<string>,...etc
Well, this is exactly what I didn't want. I wanted to know
whether I can infer the return type that way, there's nothing
interesting in binding the return type yourself.
Jiri Palecek
---
[ 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.comeaucomputing.com/csc/faq.html ]
Author: jpalecek@web.de
Date: Mon, 2 Oct 2006 00:12:18 CST Raw View
Greg Herlihy napsal:
> jpalecek@web.de wrote:
> > Hello,
> >
> > shouldn't it be possible to create functors just for function _names_,
> > not function pointers?
> >
> > The problem is that you cannot do anything if you have to pass
> > eg. an overloaded function or templated function somewhere.
>
> It is possible to obtain a function pointer to an overloaded function
> with a cast or assignment to a function pointer variable of the desired
> type. For example, given an overloaded f() function:
>
> int f(int);
> double f(long);
> template <class T>
> T f(T);
>
> a program can obtain a function pointer to either of the first two
> overloads of f() like so:
>
> int (*fIntPtr)(int) = f;
> double (*fLongPtr)(long) = f;
>
> The third f() overload is a function template; therefore it has no
> address that could be passed as a function pointer. A program must
> specify (or the compiler must be able to deduce in some way) which
> specialization of f() the function pointer refers to. Since expressions
> involving function pointers can be notoriously hard to decipher, it's
> often a good idea to use typedefs as well:
>
> typedef short (*FShortPtr)(short);
>
> FShortPtr fp = &f<short>;
Sorry, but this doesn't answer the question. If you looked at the
functor
I sketched, you'd see that it would do all these things at once. For
arguments of type int, it calls f(int), for argument of type Vector, it
calls f(Vector). You could use it eg. as a visitor for boost::variant
(and
the need to specify exact type for the function pointer is just
annoying
and error-prone).
> > You CAN create a functor for this, which will look like
> >
> > struct nameFunctor
> > {
> > template <class A,class B> Ret operator()(A a,B b) {
> > return name(a,b);
> > }
> > ... etc ...
> > }
>
> The Standard library already has a routine that returns a function
> object when passed a function pointer to a routine that accepts one or
> two parameters: std::ptr_fun(). The std::tr1 library greatly expands
> the Library's support for function objects by adding an entire function
> class class template, std::tr1::function, and a result_of class
> template to help deduce function return types. But as (hopefully) the
> first of this answer was able to make clear, none of this library
> support is needed to obtain a function pointer for any kind of
> function.
Again, I didn't ask about function _pointers_.
Regards
Jiri Palecek
---
[ 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.comeaucomputing.com/csc/faq.html ]