Pointer to templated function

J

Juha Nieminen

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?
 
K

Kai-Uwe Bux

Juha said:
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
 
A

Alf P. Steinbach /Usenet

* 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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top