C++, Function Pointer to the Template Function Pointer

Function pointer to templated function

I try something like this but I get compile errors:

Box<T> (*p)(Box<T>, Point<T>, Orientation) = dir ? f2p<T> : p2f<T>

Take a careful look at the arguments your functions take:

template <typename T>
Box<T> f2p(Box<T> const& box, Point<T> const& pt, Orientation o)
^^^^^^^^ ^^^^^^^^

All the arguments have to match exactly. In this case:

Box<T> (*p)(Box<T> const&, Point<T> const&, Orientation) = dir ? f2p<T> : p2f<T>;

Or, simply:

auto p = dir ? f2p<T> : p2f<T>;

Can we write a function which returns a function pointer to a function template?

No you cannot return a pointer to a function template, because a function template is not a function. It is a template.

// static auto GetPtr() { return X1::Do; }  // how to write such a function?

You need & to get a pointer to a member function, though Do is not a member function it is a member function template. You could return a pointer to X1::Do<int> or to X1::Do<double> but there is no pointer to X1::Do.

You can however return a functor with an overloaded call operator and that operator can be a template:

struct foo {
template <typename T>
void operator()(const T& t) {}

void operator()(int x){}
};

foo magic() { return foo{}; }

int main() {
magic()(3); // calls operator()(int)
magic()("hello world"); // calls operator()<const char[12]>
}

After rereading your question and the Q&A you link, I think you are maybe looking for this:

#include <iostream>
struct X1 {
static void Do(auto n) { std::cout << "1" << n << std::endl; }
static auto GetPtr() { return &X1::Do<int>; }
};
struct X2 {
static void Do(int n) { std::cout << "2" << n << std::endl; }
static auto GetPtr(){ return &Do; }
};

template <typename T> T magic(bool b, T t1, T t2) { return b ? t1 : t2; }

int main() {
auto l1 = magic( true, X1::GetPtr(), X2::GetPtr() );

l1(100);
}

As stated above, you cannot get a member function pointer to X1::Do but you can get a pointer to X1::Do<int>.

And as you are refering to conversion of lambdas to function pointers: Also lambdas with auto argument can only be converted to function pointers after choosing the argument type. Consider the example from cppreference:

void f1(int (*)(int)) {}
void f2(char (*)(int)) {}
void h(int (*)(int)) {} // #1
void h(char (*)(int)) {} // #2

auto glambda = [](auto a) { return a; };
f1(glambda); // OK
f2(glambda); // error: not convertible
h(glambda); // OK: calls #1 since #2 is not convertible

int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK

It is not possible to get a pointer to function of type auto(auto) (it isn't a type of a function to begin with). In all the calls above, after the conversion there is no auto anymore. Instead the requested type is deduced and a conversion to the respective function pointer is done.

Assigning function to function pointer with template parameter

The problem is that all branches of a normal if need to be valid at compile time, but only one of the branches in yours is. If T is int, then compare = &stringComp is invalid. If T is std::string, then compare = &intComp is invalid.

Instead, you need if constexpr, which was introduced in C++17 and does its comparison at compile time. It discards branches that it doesn't take as long as it's dependent on a template parameter, so it doesn't matter if they don't make sense for that type. For example:

template <typename T>
void sort(std::vector<T>& vector)
{
bool (*compare)(T a, T b);

if constexpr (std::is_same_v<T, int>) {
compare = &intComp;
} else if constexpr (std::is_same_v<T, std::string>) {
compare = &stringComp;
} else {
// Error
}

// ...
}

How to typedef template function pointer?

As @HolyBlackCat pointed out, the normal function pointer should work as you have a simple templated void function, whose template parameter does not act on both return and argument types.

template <typename T>
void someVoidFunction() {}

using fPtrType = void(*)();

int main()
{
fPtrType funPtr1 = &someVoidFunction<int>;
fPtrType funPtr2 = &someVoidFunction<float>;
fPtrType funPtr3 = &someVoidFunction<std::string>;
return 0;
}

If it was the case, that template parameters depends on the function arg and return types you should have instantiated the function pointer as well for each kind.

template <typename T, typename U>
T someFunction(U u) {}

template <typename T, typename U>
using fPtrType = T(*)(U);

int main()
{
fPtrType<int, float> funPtr1 = &someFunction<int, float>; // instance 1
fPtrType<float, float> funPtr2 = &someFunction<float, float>; // instance 2
return 0;
}

How to pass non-static member function pointer to a template function in C++?

Non-static member functions have an implicit parameter of the class type as the first parameter of the function, and it is that object which is mapped to the this pointer. That means that you need to pass an object of the class type as the first argument after the member function pointer like

<< getExecutionTime(&Obj::testFunc, obj, uniform_dist(rng), i) << std::endl;

or you can use a lambda instead like

<< getExecutionTime([&](){ obj.testFunc(uniform_dist(rng), i); }) << std::endl;

c++ Empty template function returns non-empty function pointer

Obviously, &cmd_create returns the A::command.

I am not fluent with assembly, but obviously you misunderstand the code ;).

&cmd_create<A> is a pointer to the function cmd_create<A>. This function pointer is assigned to f1. The pointer is of type void(*)(), pointer to function returning void and no arguments. No function in the code returns anything (if we do not count printf or main).

f1(); calls the function pointed to by f1. That is: cmd_create<A>. The function creates an object of type A and calls its command member function which prints the output you see on the screen.

Enabling optimizations means that the compiler emits something that has the same observable behavior. It could emit the same as it would for int main() { printf("Cmd"); }.

Deduce template parameter for a template function pointer with default template parameter

As stated in the comments, this situation was not clear in the standard until C++20, where it was cleaned up in order to better support the new feature of constrained functions. The new specification makes sense in previous language versions (ignoring the possibility of constraints), so hopefully implementations will eventually support this usage everywhere.



Related Topics



Leave a reply



Submit