I’m trying to call functions through their pointers. Compiling this code, I get errors saying that expressions of type void cannot be converted to other types, but I check whether the function returns a void or not before calling the function. Is there another way that I can accomplish this?
class FuncBase {
public:
FuncBase(string n, string ret, string arg1, string arg2): name(n), retval(ret), a1(arg1), a2(arg2) {}
string getName() const { return name; }
string getRet() const { return retval; }
string getA1() const { return a1; }
string getA2() const { return a2; }
virtual void call() = 0;
private:
string name, retval, a1, a2;
};
template <typename ret, typename arg1, typename arg2>
class Func: public FuncBase {
public:
Func(string n, string r, string ar1, string ar2, ret(*fc)(arg1, arg2)):
FuncBase(n, r, ar1, ar2), func(fc) {}
void call() {
arg1 ar1;
arg2 ar2;
cout << "You chose the " << getName() << " function" << endl;
cout << "Enter a " << getA1() << ": ";
cin >> ar1;
cout << "Enter a " << getA2() << ": ";
cin >> ar2;
if (getRet() != "void") {
ret val = (*func)(ar1, ar2);
cout << getName() << " returned " << val << endl;
}
else (*func)(ar1, ar2);
cout << endl;
}
private:
// pointer to function
ret(*func)(arg1, arg2);
};
For template instantiations where this fails,
funcis a function pointer that receives two arguments and hasvoidreturn type. That isretisvoid. A function with a void return type does not return anything. Naturally you cannot read the return value of an invocation of(*func)()because you said that there was no return value.Even though the branch that reads the return value won’t get executed, it still needs to compile and pass the static type checking. The fundamental issue here is that the calls to
*func()are dealt with at compile time and are subject compile time static type checking.This Stack Overflow question covers the exact same problem as you and the accepted answer shows how to deal with the issue