Obtaining function signature

Discussion in 'C++' started by psujkov@gmail.com, Feb 9, 2007.

  1. Guest

    Hi everybody,

    int f(int a, int b) { return a + b; };
    is it possible to obtain this function signature - int (int, int) in
    this case - for use in boost::function_traits ?
    e.g. std::cout << "f's arity : " << boost::function_traits<*obtaining
    signature from f()*>::arity << std::endl;
    please no macro solutions - only C++ (Boost MPL maybe could be useful
    - but still don't see how)

    best regards, Paul Sujkov
     
    , Feb 9, 2007
    #1
    1. Advertising

  2. Jim Langston Guest

    <> wrote in message
    news:...
    > Hi everybody,
    >
    > int f(int a, int b) { return a + b; };
    > is it possible to obtain this function signature - int (int, int) in
    > this case - for use in boost::function_traits ?
    > e.g. std::cout << "f's arity : " << boost::function_traits<*obtaining
    > signature from f()*>::arity << std::endl;
    > please no macro solutions - only C++ (Boost MPL maybe could be useful
    > - but still don't see how)
    >
    > best regards, Paul Sujkov


    The only thing I can come up with is that the output of the following
    program is:
    int __cdecl(int,int)

    but this may be OS specific. I do not know if the .name() of typeid is
    defined in the standard. If your program doesn't have to be compiled on
    more than one platform, then you may consider doing something like this.

    #include <iostream>

    int f(int a, int b) { return a + b; };

    int main ()
    {
    std::cout << typeid( f ).name();

    std::cin.get();
    }
     
    Jim Langston, Feb 9, 2007
    #2
    1. Advertising

  3. Kai-Uwe Bux Guest

    wrote:

    > Hi everybody,
    >
    > int f(int a, int b) { return a + b; };
    > is it possible to obtain this function signature - int (int, int) in
    > this case - for use in boost::function_traits ?
    > e.g. std::cout << "f's arity : " << boost::function_traits<*obtaining
    > signature from f()*>::arity << std::endl;
    > please no macro solutions - only C++ (Boost MPL maybe could be useful
    > - but still don't see how)


    I don't see any way of doing that. On the other hand, since C++ is strongly
    typed, in any context where you have the function, you know its type. So, I
    wonder which problem you are trying to solve.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Feb 9, 2007
    #3
  4. Mark P Guest

    Jim Langston wrote:
    > <> wrote in message
    > news:...
    >> Hi everybody,
    >>
    >> int f(int a, int b) { return a + b; };
    >> is it possible to obtain this function signature - int (int, int) in
    >> this case - for use in boost::function_traits ?
    >> e.g. std::cout << "f's arity : " << boost::function_traits<*obtaining
    >> signature from f()*>::arity << std::endl;
    >> please no macro solutions - only C++ (Boost MPL maybe could be useful
    >> - but still don't see how)
    >>
    >> best regards, Paul Sujkov

    >
    > The only thing I can come up with is that the output of the following
    > program is:
    > int __cdecl(int,int)
    >
    > but this may be OS specific. I do not know if the .name() of typeid is
    > defined in the standard. If your program doesn't have to be compiled on
    > more than one platform, then you may consider doing something like this.
    >
    > #include <iostream>


    #include <typeinfo>

    >
    > int f(int a, int b) { return a + b; };
    >
    > int main ()
    > {
    > std::cout << typeid( f ).name();
    >
    > std::cin.get();
    > }
    >
    >


    name() is a standard function (of type_info) however the output of this
    function, besides that it's a null-terminated string, is unspecified.
     
    Mark P, Feb 9, 2007
    #4
  5. On Fri, 09 Feb 2007 23:00:38 GMT, Mark P
    <> wrote:

    >Jim Langston wrote:
    >> <> wrote in message
    >> news:...
    >>> Hi everybody,
    >>>
    >>> int f(int a, int b) { return a + b; };
    >>> is it possible to obtain this function signature - int (int, int) in
    >>> this case - for use in boost::function_traits ?
    >>> e.g. std::cout << "f's arity : " << boost::function_traits<*obtaining
    >>> signature from f()*>::arity << std::endl;
    >>> please no macro solutions - only C++ (Boost MPL maybe could be useful
    >>> - but still don't see how)
    >>>
    >>> best regards, Paul Sujkov

    >>
    >> The only thing I can come up with is that the output of the following
    >> program is:
    >> int __cdecl(int,int)
    >>
    >> but this may be OS specific. I do not know if the .name() of typeid is
    >> defined in the standard. If your program doesn't have to be compiled on
    >> more than one platform, then you may consider doing something like this.
    >>
    >> #include <iostream>

    >
    >#include <typeinfo>
    >
    >>
    >> int f(int a, int b) { return a + b; };
    >>
    >> int main ()
    >> {
    >> std::cout << typeid( f ).name();
    >>
    >> std::cin.get();
    >> }
    >>
    >>

    >
    >name() is a standard function (of type_info) however the output of this
    >function, besides that it's a null-terminated string, is unspecified.


    But you can't use the result of typeid as a template parameter for
    boost::function_traits.

    -dr
     
    Dave Rahardja, Feb 10, 2007
    #5
  6. Guest

    On Feb 9, 10:35 pm, Dave Rahardja <> wrote:
    > On Fri, 09 Feb 2007 23:00:38 GMT, Mark P
    >
    >
    >
    > <> wrote:
    > >Jim Langston wrote:
    > >> <> wrote in message
    > >>news:...
    > >>> Hi everybody,

    >
    > >>> int f(int a, int b) { return a + b; };
    > >>> is it possible to obtain this function signature - int (int, int) in
    > >>> this case - for use in boost::function_traits ?
    > >>> e.g. std::cout << "f's arity : " << boost::function_traits<*obtaining
    > >>> signature from f()*>::arity << std::endl;
    > >>> please no macro solutions - only C++ (Boost MPL maybe could be useful
    > >>> - but still don't see how)

    >
    > >>> best regards, Paul Sujkov

    >
    > >> The only thing I can come up with is that the output of the following
    > >> program is:
    > >> int __cdecl(int,int)

    >
    > >> but this may be OS specific. I do not know if the .name() of typeid is
    > >> defined in the standard. If your program doesn't have to be compiled on
    > >> more than one platform, then you may consider doing something like this.

    >
    > >> #include <iostream>

    >
    > >#include <typeinfo>

    >
    > >> int f(int a, int b) { return a + b; };

    >
    > >> int main ()
    > >> {
    > >> std::cout << typeid( f ).name();

    >
    > >> std::cin.get();
    > >> }

    >
    > >name() is a standard function (of type_info) however the output of this
    > >function, besides that it's a null-terminated string, is unspecified.

    >
    > But you can't use the result of typeid as a template parameter for
    > boost::function_traits.
    >
    > -dr



    But you sure can use typeof() to do this. There's problems with
    boost::function_traits when using a member function though. So I've
    taken entirely too long to try and figure something clever out, but
    this is as good as I got:

    #include <iostream>

    #include <boost/type_traits/function_traits.hpp>

    template< typename R > struct fn_def0
    { static R fn() {} } ;

    template< typename R, typename T > int mem_fn_arity( R ( T::* )
    (void) )
    {
    return boost::function_traits< typeof( fn_def0<R>::fn ) >::arity ;
    }

    template< typename R, typename A1 > struct fn_def1
    { static R fn( A1 ) {} } ;

    template< typename R, typename T, typename A1 > int mem_fn_arity( R
    ( T::* )( A1 ) )
    {
    return boost::function_traits< typeof( fn_def1<R,A1>::fn )
    >::arity ;

    }

    template< typename R, typename A1, typename A2 > struct fn_def2
    { static R fn( A1, A2 ) {} } ;

    template< typename R, typename T, typename A1, typename A2 > int
    mem_fn_arity( R ( T::* )( A1, A2 ) )
    {
    return boost::function_traits< typeof( fn_def2<R,A1,A2>::fn )
    >::arity ;

    }

    class A
    {
    public:
    int foo0() {}
    int foo1( int a ) {}
    int foo2( int a, int b ) {}
    } ;

    int
    main( int argc, char* argv[] )
    {
    std::cout << boost::function_traits< typeof( main ) >::arity <<
    std::endl ;
    std::cout << mem_fn_arity( &A::foo0 ) << std::endl ;
    std::cout << mem_fn_arity( &A::foo1 ) << std::endl ;
    std::cout << mem_fn_arity( &A::foo2 ) << std::endl ;
    }

    HTH,
    Paul
     
    , Feb 10, 2007
    #6
  7. Guest

    On Feb 9, 11:17 pm, ""
    <> wrote:
    > On Feb 9, 10:35 pm, Dave Rahardja <> wrote:
    >
    >
    >
    > > On Fri, 09 Feb 2007 23:00:38 GMT, Mark P

    >
    > > <> wrote:
    > > >Jim Langston wrote:
    > > >> <> wrote in message
    > > >>news:...
    > > >>> Hi everybody,

    >
    > > >>> int f(int a, int b) { return a + b; };
    > > >>> is it possible to obtain this function signature - int (int, int) in
    > > >>> this case - for use in boost::function_traits ?
    > > >>> e.g. std::cout << "f's arity : " << boost::function_traits<*obtaining
    > > >>> signature from f()*>::arity << std::endl;
    > > >>> please no macro solutions - only C++ (Boost MPL maybe could be useful
    > > >>> - but still don't see how)

    >
    > > >>> best regards, Paul Sujkov

    >
    > > >> The only thing I can come up with is that the output of the following
    > > >> program is:
    > > >> int __cdecl(int,int)

    >
    > > >> but this may be OS specific. I do not know if the .name() of typeid is
    > > >> defined in the standard. If your program doesn't have to be compiled on
    > > >> more than one platform, then you may consider doing something like this.

    >
    > > >> #include <iostream>

    >
    > > >#include <typeinfo>

    >
    > > >> int f(int a, int b) { return a + b; };

    >
    > > >> int main ()
    > > >> {
    > > >> std::cout << typeid( f ).name();

    >
    > > >> std::cin.get();
    > > >> }

    >
    > > >name() is a standard function (of type_info) however the output of this
    > > >function, besides that it's a null-terminated string, is unspecified.

    >
    > > But you can't use the result of typeid as a template parameter for
    > > boost::function_traits.

    >
    > > -dr

    >
    > But you sure can use typeof() to do this. There's problems with
    > boost::function_traits when using a member function though. So I've
    > taken entirely too long to try and figure something clever out, but
    > this is as good as I got:
    >
    > #include <iostream>
    >
    > #include <boost/type_traits/function_traits.hpp>
    >
    > template< typename R > struct fn_def0
    > { static R fn() {} } ;
    >
    > template< typename R, typename T > int mem_fn_arity( R ( T::* )
    > (void) )
    > {
    > return boost::function_traits< typeof( fn_def0<R>::fn ) >::arity ;
    >
    > }
    >
    > template< typename R, typename A1 > struct fn_def1
    > { static R fn( A1 ) {} } ;
    >
    > template< typename R, typename T, typename A1 > int mem_fn_arity( R
    > ( T::* )( A1 ) )
    > {
    > return boost::function_traits< typeof( fn_def1<R,A1>::fn )
    >
    > >::arity ;

    > }
    >
    > template< typename R, typename A1, typename A2 > struct fn_def2
    > { static R fn( A1, A2 ) {} } ;
    >
    > template< typename R, typename T, typename A1, typename A2 > int
    > mem_fn_arity( R ( T::* )( A1, A2 ) )
    > {
    > return boost::function_traits< typeof( fn_def2<R,A1,A2>::fn )
    >
    > >::arity ;

    > }
    >
    > class A
    > {
    > public:
    > int foo0() {}
    > int foo1( int a ) {}
    > int foo2( int a, int b ) {}
    >
    > } ;
    >
    > int
    > main( int argc, char* argv[] )
    > {
    > std::cout << boost::function_traits< typeof( main ) >::arity <<
    > std::endl ;
    > std::cout << mem_fn_arity( &A::foo0 ) << std::endl ;
    > std::cout << mem_fn_arity( &A::foo1 ) << std::endl ;
    > std::cout << mem_fn_arity( &A::foo2 ) << std::endl ;
    >
    > }
    >
    > HTH,
    > Paul



    So I really suck, cause I just realized this isn't in the standard.
    But it works on compilers that support it :D

    See this article:
    http://www.codeproject.com/vcpp/stl/typeof.asp

    Paul Davis.
     
    , Feb 10, 2007
    #7
  8. On 9 Feb 2007 21:17:03 -0800, ""
    <> wrote:

    >But you sure can use typeof() to do this. There's problems with
    >boost::function_traits when using a member function though. So I've
    >taken entirely too long to try and figure something clever out, but
    >this is as good as I got:


    Unfortunately typeof() is not part of the C++ standard.

    -dr
     
    Dave Rahardja, Feb 10, 2007
    #8
  9. GRINFY Guest

    >From Infinity:

    Code snippet:
    -----------------------------------------------------------
    #include <iostream>
    using namespace std;

    int foo(int a, char * b) { return 0; };
    char * goo(int * a, string b) { return ""; };

    int main ()
    {
    cout << typeid( foo ).name() << "\n";
    cout << typeid( foo ).raw_name() << "\n\n";
    cout << typeid( goo ).name() << "\n";
    cout << typeid( goo ).raw_name() << "\n";
    cin.get();

    return 0;
    }

    Output:
    -----------------------------------------------------------
    int (__cdecl*)(int,char *)
    ..P6AHHPAD@Z

    char * (__cdecl*)(int *,class std::basic_string<char,struct
    std::char_traits<char>,class std::allocator<char> >)
    ..P6APADPAHV?$basic_string@DU?$char_traits@D@std@@V?
    $allocator@D@2@@std@@@Z


    .... Take care
     
    GRINFY, Feb 27, 2007
    #9
  10. GRINFY wrote:
    >> From Infinity:

    >
    > Code snippet:
    > -----------------------------------------------------------
    > #include <iostream>
    > using namespace std;
    >
    > int foo(int a, char * b) { return 0; };
    > char * goo(int * a, string b) { return ""; };
    >
    > int main ()
    > {
    > cout << typeid( foo ).name() << "\n";
    > cout << typeid( foo ).raw_name() << "\n\n";
    > cout << typeid( goo ).name() << "\n";
    > cout << typeid( goo ).raw_name() << "\n";
    > cin.get();
    >
    > return 0;
    > }
    >
    > Output:
    > -----------------------------------------------------------
    > int (__cdecl*)(int,char *)
    > .P6AHHPAD@Z
    >
    > char * (__cdecl*)(int *,class std::basic_string<char,struct
    > std::char_traits<char>,class std::allocator<char> >)
    > .P6APADPAHV?$basic_string@DU?$char_traits@D@std@@V?
    > $allocator@D@2@@std@@@Z
    >
    >
    > ... Take care


    Just a note: the Standard does NOT require for the implementation
    to produce any meaningful output from 'std::typeinfo::name()', and
    the strings returned are definitely implementation-specific.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Feb 27, 2007
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JJBW
    Replies:
    1
    Views:
    10,542
    Joerg Jooss
    Apr 24, 2004
  2. Replies:
    3
    Views:
    569
    =?iso-8859-1?q?Daniel_Kr=FCgler?=
    Feb 10, 2007
  3. Replies:
    1
    Views:
    411
  4. Gustavo Narea
    Replies:
    14
    Views:
    893
    Gustavo Narea
    Feb 16, 2009
  5. daniel rich
    Replies:
    5
    Views:
    327
    daniel rich
    Nov 14, 2012
Loading...

Share This Page