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
G++ Always Backward-Compatible with "Older" Static Libraries
Proper Way of Casting Pointer Types
Compiling and Running a C++ Program with Vim
"Template<>" VS "Template" Without Brackets - What's the Difference
Reading "Integer" Size Bytes from a Char* Array
Avoid Warning 'Unreferenced Formal Parameter'
What Is the Best Solution to Pause and Resume Pthreads
Decltype, Result_Of, or Typeof
Using Boost::Asio Thread Pool for General Purpose Tasks
Less Verbose Way to Declare Multidimensional Std::Array
How to Store a Lambda Expression as a Field of a Class in C++11
Getting Std::Thread/Mutex to Work Under Win7 with Mingw and G++ 4.7.2
Why Copy Constructor Is Called When Passing Temporary by Const Reference