Pointer to a void * function C++ - c++

I am trying to call pointer to a void * function inside the main method and the compiler is saying assigning to 'funcptr<g>' from incompatible type 'void *(void *). hello function is actually an argument to pthread_create function. That's why it is void * function. How can I create a function pointer to a void * function?
#include <iostream>
#include <pthread.h>
using namespace std;
template<typename T>
using funcptr = void (*T::*)(void *); // I think it is wrong here.
class m {
public:
template <typename T>
struct my_struct {
funcptr<T> ptr;
};
};
class g {
public:
static void *hello(void *);
};
int main() {
struct m::my_struct<g> h;
h.ptr = g::hello; // Error here
return 0;
}

How can I create a function pointer to a void * function?
hello is not a member function, but it's a static function.
So your funcptr should be as follows:
// No template needed.
using funcptr = void* (*)(void *)
Note that hello is declared with static, meaning that it's no longer a member function to g.
Static members of a class are not associated with the objects of the class.
So using void (*T::*)(void *) to cull non-member functions is incorrect.
If you're allowed to use a compiler that supports C++11, you don't even need to manually deduct its type anymore, using decltype:
// decltype deducts its exact type for you.
using funcptr = decltype(&g::hello);
class m
{
public:
struct my_struct
{
funcptr ptr;
};
};
FYI, since hello does not have its definition, you might encounter a linkage error. To prevent that, I assumed that there's some implementation inside:
static void *hello(void *)
{
// Meaningless, but..
return nullptr;
}

if you're using C++11, you can use std::function<> which just bothers about the return type and parameters of the function and not where they are defined and what are its type.
Here is the code using std::function<>
#include <iostream>
#include <functional>
#include <pthread.h>
using namespace std;
class m {
public:
template <typename T>
struct my_struct {
function<void*(void*)> ptr;
};
};
class g {
public:
static void *hello(void *) {
cout<<"Hello.."<<endl;
}
};
int main() {
struct m::my_struct<g> h;
h.ptr = g::hello;
h.ptr(nullptr);
return 0;
}

Related

How to use string to call function in a class?

I hope to use map library to call a function by a string with the function name, I've tested the following example and everything are working well.
#include <string>
#include <iostream>
using namespace std;
typedef void (*pFunc)();
map<string, pFunc> strFuncMap;
void func1()
{
printf("this is func1!\n");
}
void buildMap()
{
strFuncMap["func1"] = &func1;//
}
void callFunc(const std::string& str)
{
(*strFuncMap[str])();
}
int main()
{
buildMap();
callFunc("func1");
return 0;
}
However, as I define all these things in a class, there is a compiler error occur:
#include <map>
#include <string>
#include <iostream>
using namespace std;
class theClass {
public:
typedef void (*pFunc)();
map<string, pFunc> strFuncMap;
void func1()
{
printf("this is func1!\n");
}
void buildMap()
{
strFuncMap["func1"] = &func1;// a value of type cannot be assigned to an entity of type
}
void callFunc(const std::string& str)
{
(*strFuncMap[str])();
}
};
int main()
{
theClass a;
a.buildMap();
a.callFunc("func1");
return 0;
}
I've tried to solve this problem for a couple of hours. Or is there any other way to use string to call function in a class? I will very appreciate if someone can help me. THANKS!!
Your code doesn't work because func1 is a member function and the syntax for member functions is different.
You need a map of member function pointers (offsets)
typedef void (theClass::*pFunc)();
map<string, pFunc> strFuncMap;
Then you can store the pointer with
strFuncMap["func1"] = &theClass::func1;
And you need an object to call a member function
(this->*strFuncMap[str])();
The final code:
#include <map>
#include <string>
#include <iostream>
using namespace std;
class theClass {
public:
typedef void (theClass::*pFunc)();
map<string, pFunc> strFuncMap;
void func1()
{
printf("this is func1!\n");
}
void buildMap()
{
strFuncMap["func1"] = &theClass::func1;
}
void callFunc(const std::string& str)
{
(this->*strFuncMap[str])();
}
};
int main()
{
theClass a;
a.buildMap();
a.callFunc("func1");
return 0;
}
typedef void (*pFunc)();
This declares pFunc to be the type of function pointers. That is, the type of pointers to functions which exist at the top-level. This excludes member functions, lambda functions, and functors. Consider
using pFunc = std::function<void()>
Now your type will correctly accept anything that can reasonably be interpreted as a callable object. Note that member functions still need to be wrapped in a lambda, since you're closing around this.
strFuncMap["func1"] = [this]() { this->func1(); };

Converting pointer to member function to std::function

I have a slightly convoluted use case of passing a member function pointer to an outside function which is then called again by a member function (Don't ask!). I'm learning about std::function and std::mem_fn but I can't seem to be able to convert my old school function pointer
void (T::*func)(int) to a std::function<void (T::*)(int) func>
in the code below, I'd like to be able to pass a std::function to memFuncTaker in the call from anotherMember
#include "class2.hpp"
#include <iostream>
class outer{
public:
void aMember(int a){
std::cout << a <<std::endl;
}
void anotherMember(double){
memFuncTaker(this, &outer::aMember);
}
};
template<class T>
void memFuncTaker(T* obj , void (T::*func)(int) ){
(obj->*func)(7);
}
When you bind std::function to a non-static member function pointer, it "reveals" the hidden this parameter, making it the first explicit parameter of the resultant functor. So in your case for outer::aMember you'd use std::function<void(outer *, int)> and end up with a two-parameter functor
#include <functional>
#include <iostream>
template<class T>
void memFuncTaker(T *obj , std::function<void(T *, int)> func){
func(obj, 7);
}
class outer{
public:
void aMember(int a){
std::cout << a <<std::endl;
}
void anotherMember(double){
memFuncTaker(this, std::function<void(outer *, int)>{&outer::aMember});
}
};
int main() {
outer o;
o.anotherMember(0);
}
http://coliru.stacked-crooked.com/a/5e9d2486c4c45138
Of course, if you prefer, you can bind the first argument of that functor (by using std::bind or lambda) and thus "hide" it again
#include <functional>
#include <iostream>
using namespace std::placeholders;
void memFuncTaker(std::function<void(int)> func){
func(7);
}
class outer{
public:
void aMember(int a){
std::cout << a <<std::endl;
}
void anotherMember(double){
memFuncTaker(std::function<void(int)>(std::bind(&outer::aMember, this, _1)));
}
};
int main() {
outer o;
o.anotherMember(0);
}
Note that in this version memFuncTaker no longer has to be a template (which happens to be one of the primary purposes of std::function - employ type erasure techniques to "de-templatize" the code).

How to pass a non-static member function as a unique_ptr deleter [duplicate]

This question already has answers here:
How Can I Pass a Member Function to a Function Pointer?
(3 answers)
Closed 7 years ago.
#include <memory>
#include <iostream>
#include <exception>
#include <curl/curl.h>
class client
{
private:
std::unique_ptr<CURL, decltype(&psclient::del_curl)> uptr_curl_;
inline CURL * init_curl()
{
CURLcode result = curl_global_init(CURL_GLOBAL_DEFAULT);
if(result != CURLE_OK)
throw std::logic_error(curl_easy_strerror(result));
return curl_easy_init();
}
inline void del_curl(CURL * ptr_curl)
{
curl_easy_cleanup(ptr_curl);
curl_global_cleanup();
}
public:
inline client()
: uptr_curl_(init_curl(), &client::del_curl)
{
}
}
The compiler keeps complaining No matching constructor for initialization of 'std::unique_ptr<CURL, void (*)(CURL *)>'
It seems to me like the declaration is correct for the deleter template argument. It is a function pointer that returns void and takes a CURL * as an argument. This matches the signature of del_curl.
Is there yet another random rule, unknown to me, in C++ that specifies a requirement for template arguments to non-static member function pointers? If so, why?
The answer of #R. Sahu is correct imo. However, if you insist of passing a non-static member function deleter, here is a way of doing it using the good old std::bind and std::function:
#include <memory>
#include <iostream>
#include <functional>
class Foo
{
private:
std::unique_ptr<int, std::function<void(int*)>> _up;
public:
Foo(): _up(new int[42], std::bind(&Foo::deleter, this, std::placeholders::_1))
{
}
void deleter(int* p)
{
delete[] p;
std::cout << "In deleter" << std::endl;
}
};
int main()
{
Foo foo;
}
PS: I just don't like the bind, I wonder if one can improve on that.
With a lambda:
Foo(): _up(new int[42],
[this](int* p)->void
{
deleter(p);
}
){}
The second template parameter used in the declaration of uptr_curl_ is void (*)(CURL *)
The type of &client::del_curl is void (CURL::*)(CURL*).
They are not the same. You can change del_curl to a static member function. That will resolve the problem.
Update
You can use a non-static member function with the help of std::function and std::bind.
class client
{
public:
client();
private:
std::unique_ptr<CURL, std::function<void(CURL *)>> uptr_curl_;
CURL * init_curl();
void del_curl(CURL * ptr_curl);
};
client::client() : uptr_curl_(init_curl(),
std::bind(&client::del_curl, this, std::placeholders::_1))
{
// ...
}

Templates non-type parameters to a static member function

I'm trying to write a template that takes a template to a non-type parameter to a static member function:
#include <iostream>
using namespace std;
class C {
public:
static void method()
{
cout << "C::method" << endl;
}
};
typedef void (C::*pMethod)();
template<typename T, pMethod>
void callingFunction()
{
T c;
pMethod aPointerToMember = &T::method;
(c.*aPointerToMember)();
}
int main()
{
callingFunction<C, &C::method>();
return 0;
}
But I always get error when calling the function in main:
error: no matching function for call to 'callingFunction()' // mingw
If The member function is not static it works, how can I make it work with static function ?
Thanks.
Thank you
For a static member function, change your typedef to typedef void (*pMethod)(); - as if it was a free function.

C++ function pointer as a static member

I cannot figure the syntax to declare a function pointer as a static member.
#include <iostream>
using namespace std;
class A
{
static void (*cb)(int a, char c);
};
void A::*cb = NULL;
int main()
{
}
g++ outputs the error "cannot declare pointer to `void' member". I assume I need to do something with parentheses but void A::(*cb) = NULL does not work either.
I introduced a typedef, which made it somewhat clearer in my opinion:
class A
{
typedef void (*FPTR)(int a, char c);
static FPTR cb;
};
A::FPTR A::cb = NULL;
void (*A::cb)(int a, char c) = NULL;