Pointer to templated function

Discussion in 'C++' started by Juha Nieminen, Apr 17, 2011.

  1. In a discussion in another forum about curried functions, I wondered
    if this could be, technically speaking, considered currying in C++:

    //-----------------------------------------------------------------
    #include <iostream>

    void function(int a, int b, int c)
    {
    std::cout << a << " " << b << " " << c << "\n";
    }

    template<int lastValue>
    void curriedFunction(int a, int b)
    {
    function(a, b, lastValue);
    }

    int main()
    {
    void(*functionWith5)(int,int) = &curriedFunction<5>;

    functionWith5(1, 2); // Is this a curried function call?
    }
    //-----------------------------------------------------------------

    When I wrote that, I was actually kind of expecting it to not to work
    (iow. to get some kind of syntax error). However, to a bit of my surprise,
    it does work.

    I had never before thought about how one could make a pointer to a
    templated function instantiation. After all, you can't template a pointer.
    I was a bit surprised that a regular bare-bones function pointer can be
    made to point to a template function instantiation. I had a gut feeling
    that you could possibly get an error because the internal type symbols for
    a template function instantiation might be different to that of a "raw"
    function. However, apparently not. (OTOH, thinking about it, why shouldn't
    it work? How else are you supposed to take a pointer to a templated
    function instantiation?)

    Is this really legit, or is it just a fluke?
     
    Juha Nieminen, Apr 17, 2011
    #1
    1. Advertising

  2. Juha Nieminen

    Kai-Uwe Bux Guest

    Juha Nieminen wrote:

    > In a discussion in another forum about curried functions, I wondered
    > if this could be, technically speaking, considered currying in C++:


    Hm, without the qualification "technically speaking", I would say: sure, why
    not. But I don't have an opionion to offer on, whether the code below
    satisfies some technical definition of currying. Surely, I would first think
    about std::bind() as templates are limited: (a) the fixed value has to be
    known at compile time and (b) cannot have an arbitrary type.

    > //-----------------------------------------------------------------
    > #include <iostream>
    >
    > void function(int a, int b, int c)
    > {
    > std::cout << a << " " << b << " " << c << "\n";
    > }
    >
    > template<int lastValue>
    > void curriedFunction(int a, int b)
    > {
    > function(a, b, lastValue);
    > }
    >
    > int main()
    > {
    > void(*functionWith5)(int,int) = &curriedFunction<5>;
    >
    > functionWith5(1, 2); // Is this a curried function call?
    > }
    > //-----------------------------------------------------------------
    >
    > When I wrote that, I was actually kind of expecting it to not to work
    > (iow. to get some kind of syntax error). However, to a bit of my surprise,
    > it does work.
    >
    > I had never before thought about how one could make a pointer to a
    > templated function instantiation. After all, you can't template a pointer.
    > I was a bit surprised that a regular bare-bones function pointer can be
    > made to point to a template function instantiation. I had a gut feeling
    > that you could possibly get an error because the internal type symbols for
    > a template function instantiation might be different to that of a "raw"
    > function. However, apparently not. (OTOH, thinking about it, why shouldn't
    > it work? How else are you supposed to take a pointer to a templated
    > function instantiation?)
    >
    > Is this really legit, or is it just a fluke?


    It is, as far as I know, legit. A prominent use case: one can that technique
    to implement the custom deleter in shared_ptr<> or the clone function in
    smart pointers with deep copy semantics. There, however, the template
    parameter would be a type, not a value.


    Best,

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Apr 17, 2011
    #2
    1. Advertising

  3. * Juha Nieminen, on 17.04.2011 11:32:
    > In a discussion in another forum about curried functions, I wondered
    > if this could be, technically speaking, considered currying in C++:
    >
    > //-----------------------------------------------------------------
    > #include<iostream>
    >
    > void function(int a, int b, int c)
    > {
    > std::cout<< a<< " "<< b<< " "<< c<< "\n";
    > }
    >
    > template<int lastValue>
    > void curriedFunction(int a, int b)
    > {
    > function(a, b, lastValue);
    > }
    >
    > int main()
    > {
    > void(*functionWith5)(int,int) =&curriedFunction<5>;
    >
    > functionWith5(1, 2); // Is this a curried function call?
    > }
    > //-----------------------------------------------------------------
    >
    > When I wrote that, I was actually kind of expecting it to not to work
    > (iow. to get some kind of syntax error). However, to a bit of my surprise,
    > it does work.
    >
    > I had never before thought about how one could make a pointer to a
    > templated function instantiation. After all, you can't template a pointer.
    > I was a bit surprised that a regular bare-bones function pointer can be
    > made to point to a template function instantiation.


    The instantiation (or full specialization) is in effect an ordinary function.

    In some cases that ordinariness can bite you.

    For example, in a header file it's OK to define ...

    template< class Type >
    int foo() { return sizeof( Type ); } // Or whatever.

    .... but a specialization like ...

    template<>
    int foo<float>() { return sizeof(float); }

    .... is bad bad bad -- because of lacking keyword "inline", which is
    practically needed for an ordinary function definition in a header file.


    > I had a gut feeling
    > that you could possibly get an error because the internal type symbols for
    > a template function instantiation might be different to that of a "raw"
    > function. However, apparently not. (OTOH, thinking about it, why shouldn't
    > it work? How else are you supposed to take a pointer to a templated
    > function instantiation?)
    >
    > Is this really legit, or is it just a fluke?


    It's OK.

    But I'm not sure about the terminology; I'd have to look up "currying"; mostly
    it reminds me of certain heavily spiced Pakistani dinners (and just a little
    functional programming and academic things)...

    Also, it's pretty limited: the template argument needs to an integer-based type
    or pointer.

    Argh, more terminology; I can't recall what that is called.

    But anyway, check out Boost 'bind' for more general functionality like that.


    Cheers & hth.,

    - Alf

    --
    blog at <url: http://alfps.wordpress.com>
     
    Alf P. Steinbach /Usenet, Apr 17, 2011
    #3
    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. RA Scheltema
    Replies:
    3
    Views:
    406
    RA Scheltema
    Jan 6, 2004
  2. Marijn
    Replies:
    5
    Views:
    469
    Marijn
    Feb 13, 2004
  3. Replies:
    0
    Views:
    2,238
  4. Amadeus W. M.
    Replies:
    2
    Views:
    396
    Amadeus W. M.
    Jul 4, 2006
  5. chhenning
    Replies:
    5
    Views:
    366
    chhenning
    Feb 13, 2008
Loading...

Share This Page