Interpreting static_cast "static_cast<void (Pet::*)(int)>" syntax? - c++

I'm trying to understand the static cast as used in the Pybind11 docs here. Specifically, they use the syntax
static_cast<void (Pet::*)(int)>(&Pet::set)
Since I haven't seen this syntax before I'm strugling to interpret and apply to my own code so I was hoping somebody could explain what's going on here. Thanks
Edit - some context
I am creating Pybind11 bindings to an overloaded method that has two signatures, which only differ by const qualification. The class I am binding is a template so I am using this strategy to create the bindings
template<class T>
class Matrix {
public:
...
/**
* get the row names
*/
std::vector<std::string> &getRowNames() {
return rowNames;
}
/**
* get the row names (mutable)
*/
const std::vector<std::string> &getRowNames() {
return rowNames;
}
...
My version of the helper function described in that post is this:
template<typename T>
void declare_matrix(py::module &m, const std::string &typestr) {
using Class = ls::Matrix<T>;
const std::string &pyclass_name = typestr;
py::class_<Class>(m, pyclass_name.c_str(), py::buffer_protocol(), py::dynamic_attr())
.def(py::init<unsigned int, unsigned int>())
.def("getRowNames", static_cast<const std::vector<std::string>(ls::Matrix<T>::*)()>(&ls::Matrix<T>::getRowNames))
but the getRowNames line produces the following error:
Address of overloaded function 'getRowNames' cannot be static_cast to type 'const std::vector<std::string> (ls::Matrix<complex<double>>::*)()'
For anybody else reading this, the cast I was able to figure out thanks to the answer is:
static_cast< std::vector<std::string>& (ls::Matrix<T>::*)()>(&Class::getRowNames)

The meaning of:
static_cast<void (Pet::*)(int)>(&Pet::set)
static_cast<T_1>(T_2) means we're casting type 2 to type 1.
T_1:
(Pet::*) is a pointer to a class member of Pet (see https://stackoverflow.com/a/9939367/14344821 for a further discussion)
void (Pet::*)(int) is a pointer to a member function that takes an int parameter, returning a void
T_2
&Pet::set is the memory location of Pet::set
So basically, we're stating explicitly that we are setting the integer value.
Now we can bind the set functions to python (allowing us to set both age and name):
.def("set", static_cast<void (Pet::*)(int)>(&Pet::set), "Set the pet's age")
.def("set", static_cast<void (Pet::*)(const std::string &)>(&Pet::set), "Set the pet's name");

Related

How can i pass a function as a function parameter in another function?

I am trying to use an Arduino library and to use one of it's functions as a parameter in my own function, but I don't know how can I do that.
I tried the code below but I get an error.
Any help will be appreciated.
P.S: I do not have an option to use auto keyword.
using namespace httpsserver;
HTTPServer Http;
typedef void (*Register)(HTTPNode*); // My typedef
Register Node = Http.registerNode;
When I am trying to call Node (...), I get the error below.
Cannot convert 'httpsserver::ResourceResolver::registerNode'
from type 'void (httpsserver::ResourceResolver::)(httpsserver::HTTPNode*)'
to type 'Register {aka void (*)(httpsserver::HTTPNode*)}'
How can I create a function pointer for the type :
'void (httpsserver::ResourceResolver::)(httpsserver::HTTPNode*)'
I want to use it as a parameter in another function:
// My Declaration
void Get(void(*Register)(httpsserver::HTTPNode*), const std::string& path);
// Usage
Get (Http.registerNode(...), ""); // Like so
How can I do that?
A member function pointer is not a function pointer.
typedef void (httpsserver::*Register)(HTTPNode*); // My typedef
Register Node = &httpsserver::registerNode;
usage:
void Get(void(httpsserver::*Register)(httpsserver::HTTPNode*), const std::string& path);
Get (&httpsserver::registerNode, "");
you have to pass the httpsserver::HTTPNode* into Register within Get.
If you want to bind the arguments to the function object and call it later, you want std::function<void()>:
void Get(std::function<void()>, const std::string& path);
Get ([&]{ Http.registerNode(...); }, "");
note, however, that this makes lifetime of the objects refered to within the {} above quite dangerous.

Compiler error wrapping an interpretable function

I have a legacy C code base, which I am migrating to C++ in a piecemeal fashion. It includes an interpreter, so there is a need to wrap static functions and arguments for use by the interpreter. So a typical function for export to the interpreter may have the following signature:
static void do_strstr(struct value * p)
and be exposed to the interpreter like so:
using vptr = void (*) ();
template <typename Func>
constexpr vptr to_vptr(Func && func)
{ return reinterpret_cast<vptr>(func); }
struct function string_funs[] = {
...
{ C_FN3, X_A3, "SSI", to_vptr(do_strstr), "find" },
...
};
This has been proven to work. The drawback with the method so far is that the called function must allocate memory onto a temporary stack. An improvement would be where the called function just returns a string, for example. This function is then wrapped, where the wrapper does the memory magic behind the scenes. This allows functions to created in a more vanilla way.
Here is an implementation which concatenates two strings using my improved method:
static std::string do_concata(struct value* p)
{
std::string s1 = (p)->gString();
std::string s2 = (p+1)->gString();
return s1+s2;
}
I create a helper function:
static void do_concata_1(struct value* p)
{
wrapfunc(do_concata)(p);
}
where the somewhat generic wrapper is defined as:
std::function<void(struct value*)>
wrapfunc(std::function<std::string(struct value*)> func)
{
auto fn = [=](struct value* p) {
std::string s = func(p);
char* ret = alloc_tmp_mem(s.size()+1);
strcpy(ret, s.c_str());
p->sString(ret);
return;
};
return fn;
}
which is exposed to the interpreter as follows:
struct function string_funs[] = {
...
{ C_FN2, X_A2, "SS", to_vptr(do_concata_1), "concata" },
...
};
I am not satisfied with this solution, though, as it requires a helper function for each function I define. It would be better if I could eliminate do_concata_1 and write another function that wraps the wrapfunc.
And this is where the problem is. If I write:
vptr to_vptr_1(std::function<void(struct value*)> func)
{
return to_vptr(wrapfunc(func));
}
then the compiler complains:
stringo.cc: In function ‘void (* to_vptr_1(std::function<void(value*)>))()’:
stringo.cc:373:30: error: could not convert ‘func’ from ‘std::function<void(value*)>’ to ‘std::function<std::__cxx11::basic_string<char>(value*)>’
return to_vptr(wrapfunc(func));
which is bizarre in my mind, because where did the std::__cxx11::basic_string<char> come from? It should be void, surely?
I'm at a loss to see what the fix should be. I am also a bit confused as to whether I should be passing copies of functions, references to functions, or the enigmatic && r-vale references.
In to_vptr_1(), func is established as a function that returns void. But func is passed to wrapfunc(), which expects a function that returns std::string. The compiler does not have a way to convert func from std::function<void(struct value*)> to std::function<std::string(struct value*)>, so it emits the error message.
reinterpret_cast from std::function to raw function pointer is not going to work. This question has some good discussion on the topic, and this one has a solution that could perhaps be reworked for this situation.

Make function pointer from an already declared function

I have a function declared as int __stdcall MyFunction(int param, int param); and I need to get a type of the pointer to the function in a macro or a template when the name is passed as a parameter.
Is this possible in C++ or do I have to rewrite the function signature myself?
You can make a type alias for a function pointer (to which it decays, or which is returned by the address-of operator) the following way:
#include <iostream>
int MyFunction(int param, int param1)
{
std::cout << param << " " << param1 << std::endl;
return 0;
}
using Myfunction_ptr_t = std::decay<decltype(MyFunction)>::type;
// or using Myfunction_ptr_t = decltype(&MyFunction);
// or using Myfunction_ptr_t = decltype(MyFunction) *;
int main()
{
Myfunction_ptr_t Myfunction_ptr = MyFunction;
Myfunction_ptr(1, 2);
}
This example should rather use the auto specifier (since C++ 11):
auto Myfunction_ptr = MyFunction;
but that won't help in non-deducible context.
Function pointer behaves like every other pointer. It is a memory address which points to some entity (function code in this case). You can save these pointers somewhere and then fetch them in any convenient for your situation way.
For example you can create static map of std::string vs fun. pointer pairs:
static std::map<std::string, PTR_TYPE> funMap;
After that save pointers to this map and retreive them when needed.
If you don't have pointer yet, probably you speak about exported functions from libraries. In this case look at ldd for *nix-based or somethig simialar for other platform. You will need to search for runtime linker information and find fnction by it's name.
Actually I don't understand why you say you can't link against those functions. Do it in standard way: include header file with such declarations. Use declaration. Linker will do the work for you. Just provide it a path to library with those functions. It will link dynamically to required functions. That's all what you should do. If you don't have such library you need to search for function at runtime manualy with the help of (again) linker at runtime.
You could define a typedef like below:
typedef int (__stdcall *MYFUN)(int, int);
Test case:
int main() {
MYFUN f = MyFunction;
f(2, 3);
}
Alternatively, you could use a std::function object as bellow:
std::function<decltype(MyFunction)> myfun;
Test case:
std::function<decltype(MyFunction)> myfun = MyFunction;
myfun(4, 5);
Live Demo
Got it. decltype(FunctionName)* pointer; will do the job.
You could use decltype or auto, like the following
decltype(&FunctionName) pointer = &FunctionName;
or
auto pointer = &FunctionName;
I avoid manually translating function pointers to types myself in C++11 and C++14 :)

C++ Store Function without Argument

Say that you define a callback function as such:
typedef std::function<void(float)> Callback;
And you have a function as such:
void ImAFunction(float a)
{
//Do something with a
}
Is there a way to be able to store a function without an argument then pass one to it at a later time?
Such as this:
//Define the Callback storage
Callback storage;
storage = std::bind(ImAFunction, this);
//Do some things
storage(5);
This wont work which I explain with some of my real code below.
I can get close to what I wan't if I bind the value in with the std::bind function. Such as:
//Change
//storage = std::bind(ImAFunction, this);
storage = std::bind(ImAFunction, this, 5.0); //5.0 is a float passed
This works but when I go to pass a value through the function the outcome is whatever I set it to before:
storage(100); //Output is still 5
I am basing the fact that I think this is possible on this article.
http://www.cprogramming.com/tutorial/function-pointers.html
It doesn't use the function or bind functions but it does pass pointer arguments and performs exactly what I need. The reason I don't just skip the bind function is because I am trying to store the function in a class (private) and I can't store it if it's a template because it's created with the class.
The error produced above comes from this code:
struct BindInfo {
Callback keyCallback;
int bindType;
bool isDown;
bool held;
std::string name;
};
template <class T1>
void bindEvent(int bindType, T1* keydownObj, void(T1::*keydownF)(float), std::string name)
{
BindInfo newKeyInfo = { std::bind(keydownF, keydownObj), bindType, false, false, name };
inputBindings.insert(std::pair<int, BindInfo>(BIND_NULL, newKeyInfo));
};
The error is:
No viable conversion from '__bind<void(Main::*&)(float), Main *&>' to 'Callback' (aka 'function<void (float)>'
Is this possible? Thanks in advance.
You can include a placeholder for an unbound argument:
std::bind(&Main::ImAFunction, this, std::placeholders::_1);
If you find that a bit of a mouthful, a lambda might be more readable:
[this](float a){ImAFunction(a);}
It sounds like what you're looking for is a function pointer. While I don't have a lot of experience using them in C++ I have used them in C so: Yes, it is possible. Perhaps something like this:
void (*IAmAFunctionPointer)(float) = &IAmAFunction;
The best way to think about that line is, that IAmAFunctionPointer is a pointer (hence the *), it returns a void, and takes a float. Then later:
float a = 5;
IAmAFunctionPointer(a);
You could even design it so that the callback function is passed into the method (I assume this is what you're looking for).
void DoStuffThenCallback(float a, void (*callback)(float))
{
//DoStuff
callback(a);
}
further reading: http://www.cprogramming.com/tutorial/function-pointers.html

how to solve following problem in C++?

I have one template function which will take a pointer type and i have instantiated it before calling.
i have written function with its dummy implementation as follows:
template<T>fun_name( const T *p )
{
//written functionality which will give me class name that i will store into string Variable
e.g. i got output like this string Var = "First_class" or string Var = "Second_class"
//Using this class name i will call one function of that class
if(Var == "Fisrt_class")
{
First_class::static_function_name(p);
}
if(Var == "Second_class")
{
Second_class::static_function_name(p);
}
}
and in global scope i instantiated this function for two variables as like below:
template<first_class>static_function_name(const First_class *)
template<Second_class>static_function_name(const Second_class *)
above code gives me error that
error: no matching function call in Second_class::static_function_class(const Fisrt_class*)
error: no matching function call in First_class::static_function_class(const Second_class*)
thanks in advance!
I think this :
template<typename T> // template<class T> is equally valid!
void fun_name( const T *p )
{
T::static_function_name(p);
}
is enough!
Two more errors is fixed in the above code:
Mention the keyword typename in template<T> in your code. You can also write template<class T> which is equally valid.
Mention the return type of the function template as well.
Your function template "calls" each of the static functions in each class. Even though program flow may never get to one of the calls, the compiler still has to figure out the code for each of them.
So when you instantiate:
template<first_class>fun_name(const first_class*)
the compiler tries to compile the entire function with T = first_class, which means at some point inside the function, it will try to compile the function call:
Second_class::static_function_name(p);
But since variable p is a pointer to first_class, the compiler doesn't find the function.
If you want conditional compilation, try specializing your function instead so the compiler only compiles the function call you intended for each type:
template <T> fun_name (const T* p);
template <> fun_name<first_class>(const first_class* p) {
first_class::static_function_name(p);
}
template <> fun_name<second_class>(const second_class* p) {
second_class::static_function_name(p);
}
Alternatively, you can use member functions which seem to be intended for what you are trying to do here. Then you can create objects and call the functions directly:
first_class f;
second_class s;
f.function();
s.function();
try changing to ,
template<typename T>
void fun_name( const T *p )
{
T::static_function_name(p);
}