Error in Function pointers with C++ - c++

Why is the following code results in error :
class A {
public:
typedef void (A::*funptr)(void);
void fun(void ) {
cout << " Fun Call " <<endl;
}
void foo(void ) {
cout << " Foo Call " <<endl;
}
funptr p[2];
funptr q;
A()
{
p[0]=&A::foo;
p[1]=&A::fun;
q =&A::fun;
}
};
int main ()
{
A obj;
(obj.*q)(void);
//(obj.p[0])();
//(obj.p[1])();
return 0;
}

You will need to call it like this:
(obj.*obj.q)();
The .* operator doesn't take a member name on the right-hand side, but rather an expression that evaluates to a member pointer. When you write this:
(obj.*q)();
It is looking for a variable called q, but there is no such variable in scope.

Change all occurrences of (void) to (). On the declarations it's redundant, and on the call itself it's not allowed.

Related

How can I call a function from an array of functions via its index?

A beginner's question I couldn't find answered online, likely because I don't know the terminology.
I want to call one of a list of procedures based on a computed index value. That is, given a '1', invoke firstProc(), '2' invokes secondProc() and so on.
All the procedures are void functions with no arguments.
I can implement that with switch/case, but what I'd prefer is something like:
void* action[2] {*firstProc, *secondProc};
(This compiles, but warns: invalid conversion from 'void (*)()' to 'void*')
and then later:
action[get_index()]();
The compiler objects that 'action' can't be used as a function.
This must be possible, right? I've tried several variations but I can't get past the use of the selected ('action[index]') as a function.
There are two equivalent ways to do what you want. The explanation is given as comments in the code snippets.
Method 1
#include <iostream>
void foo()
{
std::cout << "Hello";
}
void foo2()
{
std::cout << " wolrd!";
}
int main()
{
void (*a)() = foo;// a is a pointer to a function that takes no parameter and also does not return anything
void (*b)() = foo2;// b is a pointer to a function that takes no parameter and also does not return anything
//create array(of size 2) that can hold pointers to functions that does not return anything and also does not take any parameter
void (*arr[2])() = { a, b};
arr[0](); // calls foo
arr[1](); //calls foo1
return 0;
}
Method 1 can be executed here.
In method 1 above void (*a)() = foo; means that a is a pointer to a function that takes no parameter and also does not return anything.
Similarly, void (*b)() = foo2; means that b is a pointer to a function that takes no parameter and also does not return anything.
Next, void (*arr[2])() = { a, b}; means that arr is an array(of size 2) that can hold pointers to functions that does not return anything and also does not take any parameter.
Method 2
#include <iostream>
void foo()
{
std::cout << "Hello";
}
void foo2()
{
std::cout << " wolrd!";
}
int main()
{
//create array(of size 2) that can hold pointers to functions that does not return anything
void (*arr[2])() = { foo, foo2};
arr[0](); // calls foo
arr[1](); //calls foo1
return 0;
}
Method 2 can be executed here.
You need the correct syntax for your function pointer array. void(*func_ptr[])().
Example:
void func1() { std::cout << "Hallo" << std::endl; }
void func2() { std::cout << "World" << std::endl; }
// if you need a different signature for your functions like:
int func3(int n) { std::cout << "n1 " << n << std::endl; return n*2; }
int func4(int n) { std::cout << "n2 " << n << std::endl; return n*3; }
int main()
{
// array of function pointer which
// have no parameter and void as return value
void(*func_ptr[])()={ func1, func2 };
for ( unsigned int idx = 0; idx<2; idx++ )
{
func_ptr[idx]();
}
// array of function pointers with int return value and int as
// parameter
int(*func_ptr2[])(int)={ func3, func4 };
for ( unsigned int idx = 0; idx<2; idx++ )
{
std::cout << "retval: " << func_ptr2[idx](6) << std::endl;
}
}
I've stopped using function pointers (though they still can be useful).
I usually use std::function (and lambdas) when working with functions
Code for arrays of functions then look like this.
I used std::vector but std::array for fixed size should work fine too.
#include <vector>
#include <functional>
#include <iostream>
void some_function()
{
std::cout << "some function\n";
}
int main()
{
// std::function, abstraction of a function, function signature = template parameter, so void () is function returning a void, no parameters
// std::vector, runtime resizable array
// constructor : 4 time a lambda function printing out hello world.
std::vector<std::function<void()>> functions(4, [] { std::cout << "Hello World!\n"; } );
// easy syntax to assign an existing function to an index
functions[1] = some_function;
// replace a function in the vector with another one (lambda)
functions[2] = [] { std::cout << "booh\n"; };
// call function at index 0
functions[0]();
std::cout << "\n\n";
// or loop over all the functions and call them (classic for loop)
for (std::size_t n = 0; n < functions.size(); ++n) functions[n]();
std::cout << "\n\n";
// or loop over all the functions (range based for loop)
for (const auto& function : functions) function();
return 0;
}

Cannot pass shared_ptr argument to function pointer

I have a problem with the code that uses function pointer that takes shared_ptr argument.
Here is a sample code.
header.h
#include <functional>
#include <iostream>
template <class T> class FuncWrapper{
private:
void (*original_function)(T a);
public:
void setFunction(void *func);
void execFunction(T a, void *data);
};
template <class T> void FuncWrapper<T>::setFunction(void *func){
original_function = (void (*)(T))func;
}
template <class T> void FuncWrapper<T>::execFunction(T a, void *data){
FuncWrapper<T>* wrapper = (FuncWrapper<T>*)data;
std::cout << "inside wrapper " << *(a.get()) << std::endl;
wrapper->original_function(a);
}
main.cpp
#include <iostream>
#include <memory>
#include "header.h"
class ClassA{
public:
ClassA(std::shared_ptr<int> a){
FuncWrapper<std::shared_ptr<int>> *fw;
fw = new FuncWrapper<std::shared_ptr<int>>;
fw->setFunction((void*)&ClassA::print_int);
std::function<void(std::shared_ptr<int>)> g = std::bind(&FuncWrapper<std::shared_ptr<int>>::execFunction, fw, std::placeholders::_1, fw);
g(a);
delete fw;
}
private:
void print_int(std::shared_ptr<int> x) {
std::cout << "printing int" << std::endl;
std::cout << "given int " << *(x.get()) << std::endl;
}
};
int main(int argc, char * argv[]){
std::shared_ptr<int> x = std::make_shared<int>(10);
std::cout << "inside main " << *(x.get()) << std::endl;
ClassA *temp;
temp = new ClassA(x);
delete temp;
return 0;
}
Result
inside main 10
inside wrapper 10
printing int
Segmentation fault (core dumped)
I cannot figure out why it causes segmentation fault.
Changing std::shared_ptr<int> to int works just fine.
Therefore I assume that it has to do with owenership of shared_ptr, but I'm not familiar with smart pointers and I'm completely at loss.
I want to know
why it does not work
how to make it work
Limitations are
w/o changing print_int function itself
execute function within FuncWrapper<T>::execFunction
FuncWrapper<T>::execFunction has to be static
Otherwise, it is free to change. (inside ClassA constructor, inside main execFunction etc.)
The problem is not the shared_ptr, but mismatch between pointers to a function and a member function.
Your function wrapper expects a pointer to a function (void (*)(std::shared_ptr<int>)), but you provide a pointer to a member function (void (ClassA::*)(std::shared_ptr<int>)), which is different. An implicit leading argument of pointer to this is added to it.
This is how it really looks like:
// pointer to member function
void (*)(ClassA *ptr, std::shared_ptr<int>)
Your shared_ptr goes to the first argument and fortunately the application segfaults.
One of the solutions is to make the function print_int static.
class ClassA{
public:
ClassA(std::shared_ptr<int> a){
FuncWrapper<std::shared_ptr<int>> *fw;
fw = new FuncWrapper<std::shared_ptr<int>>;
fw->setFunction((void*)&ClassA::print_int);
std::function<void(std::shared_ptr<int>)> g = std::bind(&FuncWrapper<std::shared_ptr<int>>::execFunction, fw, std::placeholders::_1, fw);
g(a);
delete fw;
}
private:
static void print_int(std::shared_ptr<int> x) {
std::cout << "printing int" << std::endl;
std::cout << "given int " << *(x.get()) << std::endl;
}
};
But there seems to be another problem in your code. Function pointers should not be converted to object pointers (which void * is). Maybe change your setFunction this way:
void setFunction(void (*func)(T)) {
original_function = func;
}
More on that here

How to call a C++ class method, which is given as a parameter?

I'm trying to pass a method as a parameter to other method.
Magner.h:
Class Manager{
public:
timeCount(void (Manger::*function)(void));
void passedFuction();
}
In Manager.cpp, I'm trying to call timeCount by
timeCount(&Manager::passedFuction());
TimeCount Body:
void Manager::timeCount(void(Manager::*function)(void))
{
std::cout << "It works";
(*function)(); // here is error
}
ViusalStudio says:
void*Manager::*function)() operand of '*' must be a pointer
How should i correct it?
The example i was learing by was : http://www.cplusplus.com/forum/beginner/6596/
A pointer-to-member-function (pmf) is not a pointer. Let me repeat that:
A pointer-to-member-function is not a pointer.
To call a pmf, you have to provide it with the object you want to call it on. You probably want:
(this->*function)();
If you had another object obj of the right type, you could also use:
(obj.*function)();
The void (Manger::*function)(void) syntax is for member functions of Manager class, which cannot be used with functions outside the Manager class.
To fix this shortcoming, pass std::function<void(void)> instead, which would let you invoke itself using the regular function invocation syntax:
void Manager::timeCount(std::function<void(void)> f) {
std::cout << "It works";
f();
}
Here is a complete demo of how to call timeCount with member and non-member functions:
struct Manager {
string name;
void timeCount(std::function<void(void)> f) {
std::cout << "This is " << name << " manager" << endl;
f();
}
};
void foo() {
cout << "I'm foo" << endl;
}
struct Test {
int x;
void bar() {
cout << "I'm bar " << x << endl;
}
};
int main() {
Manager mgr {"time"};
mgr.timeCount(foo);
Test tst = {234};
mgr.timeCount(std::bind( &Test::bar, tst));
return 0;
}
Demo.
Since c++17, we have std::invoke:
std::invoke(function, this);
or
std::invoke(function, *this);
are both ok. Minimal demo:
#include <functional>
#include <iostream>
class Manager
{
public:
void timeCount(void (Manager::*function)(void));
void passedFuction()
{
std::cout << "call passedFunction\n";
}
};
void Manager::timeCount(void (Manager::*function)(void))
{
std::cout << "It works\n";
std::invoke(function, *this);
// (*function)(); // here is error
}
int main()
{
Manager a;
a.timeCount(&Manager::passedFuction);
}
It works
call passedFunction
live demo

Weird template and member function pointer error (C2373, C2530)

I came up with the following code when learning signal & slot, template, and function pointer.
Basically I am trying to make 2 classes, the base one will takes normal function pointers while the derived one will takes member function and wrap it up with a normal function, then pass it to the base class for invoking.
Here is the code:
#include<iostream>
struct foo {
void onNotify(int a, int b) {
std::cout << "member function: this=" << this << " a=" << a << " b=" << b << "\n";
}
};
void onNotify(void*, int a, int b) {
std::cout << "normal function: no context needed! a=" << a << " b=" << b << "\n";
}
// invoker that will takes normal functions.
template <typename...>
class invoker{
public:
invoker(void (*fptr)(void*, int, int), void* context){
fptr(context, 1, 2);
}
private:
invoker(){}
};
// invoker that will takes member functions.
template<class T>
class invoker<T> : public invoker<>{
public:
invoker<T>(T* context) : invoker<>(&forwarder, context){}
private:
invoker<T>(){}
static void forwarder(void* context, int i0, int i1) {
static_cast<T*>(context)->onNotify(i0, i1);
}
};
int main()
{
invoker<>(&onNotify, 0); // OK.
invoker<foo>(new foo); // OK.
invoker<foo>(0); // OK.
foo foo_;
auto f = invoker<foo>(&foo_); // OK.
// Errors:
// C2373 : 'foo_' : redefinition; different type modifiers.
// C2530 : 'foo_' : reference must be initialized.
invoker<foo>(&foo_); // ERROR!
return 0;
}
My questions are:
1) What is causing the compile error?
2) Why invoker<foo>(0); will actually run without error?
Thanks in advance!
1) The problem is that
invoker<foo>(&foo_);
is parsed as a definition of variable foo_ that has type invoker<foo>& rather than a call to the ctor of invoker<foo>. There is a number of ways to fix this, for example, use extra parentheses:
(invoker<foo>)(&foo_);
2) The code
invoker<foo>(0);
compiles without an error because it's unambiguous (it can't be interpreted as a declaration).

How to specify the return type of a function that returns pointer of one overloaded function using decltype?

How to specify the return type of a function that returns pointer of specific one overloaded function using decltype?
Like this:
void fun(int a) {
cout << "void fun(int a) : " << a << endl;
}
void fun(double a) {
cout << "void fun(double a) : " << a << endl;
}
decltype(?) *getFcnPtr() {
return fun;
}
What if I want getFcnPtr to just return the void fun(int a) version?
Actually, I'm reading C++ Primer and are thinking over the decltype.
I know I can use this form:
void (*getFcnPtr()) (int a) {
return fun;
}
Or with unoverloaded function, decltype(FcnName) *getFcnPtr will do the work, but what to do with decltype to specify the return type of getFcnPtr if I want to return an overloaded function?
Is it possible for decltype to be used this way? Is there a way that can add parameters to help? Something like decltype(void(int)) or decltype(fun(int)), of course these two do not work...