Please help - templates and function pointers

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void extf(int a) { }

template<typename P>
struct A {
	// 1
	template< void (*F)(P) >
	static void call(P arg) {
		(*F)(arg);
	}
	// 2
	static void call2(void (*F)(P), P arg)  {
		call< F >(arg);
	}
};

A<int>::call<&extf>(1);
A<int>::call2(&extf, 1); // error 


Why it is not working? What would be a proper way to pass function pointer as a template parameter?
How does the address of extf get passed into call()? It's passed to call2(), but not passed on to call().
> Why it is not working?

It is not an '&id-expression' - ie, address of an id-expression


> What would be a proper way to pass function pointer as a template parameter?

As it was done in A<int>::call<&extf>(1); // address of id-expression .

Or just A<int>::call<extf>(1); // & omitted in address of id-expression
It still does not solve the problem with passing the func-address (as in call2()) to be a template-argument for the call() function. Compiler complains at call< F >(arg); because "'F' is not a valid template argument for type 'void (*)(int)' because 'F' does not have external linkage"

I thought of using <typename T, T t> syntax but I have no idea how to use it with function pointer :)

> It still does not solve the problem with passing the func-address
> (as in call2()) to be a template-argument for the call() function.

What is the problem? Once we have the address of a function, we call call it using the address.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

template < typename T > struct A
{
	template< void (*FN) (T) > static void call( T arg ) { FN(arg) ; }

	static void call( void (*fn)(T), T arg ) { fn(arg) ; }
};

void foo( int a ) { std::cout << "foo(" << a << ")\n" ; }

int main()
{
    A<int>::call<foo>(1) ;

    A<int>::call( foo, 2 ) ;
}

http://ideone.com/YQBDwl

Generalized:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

struct A
{
    template< typename FN, typename... ARGS >
    static void call( FN fn, ARGS... args ) { fn(args...) ; }
};

void foo( int a ) { std::cout << "foo(" << a << ")\n" ; }

int main()
{
    A::call( foo, 1 ) ;

    const auto bar = [] ( int a, double b )
    { std::cout << "main::bar(" << a << ',' << b << ")\n" ; } ;

    A::call( bar, 2, 3.4 ) ;
}

http://ideone.com/ImIZpV
Last edited on
>> It still does not solve the problem with passing the func-address
>> (as in call2()) to be a template-argument for the call() function.

> What is the problem? Once we have the address of a function, we call call it using the address.

That is correct. But that is not the issue. The problem is with passing the function address to be a template argument just as in call2().

1
2
3
static void call2(void (*F)(P), P arg)  {
	call< F >(arg);
}


> The problem is with passing the function address to be a template argument just as in call2().

So what are you trying to say? That the C++ standard must be amended so as to allow something that is not a constant expression to be a template non-type argument?
Topic archived. No new replies allowed.