0

我试图通过它们的指针调用函数。编译这段代码时,我收到错误说 void 类型的表达式不能转换为其他类型,但我在调用函数之前检查函数是否返回 void。还有另一种方法可以做到这一点吗?

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);
}; 
4

2 回答 2

4

对于失败的模板实例化,func是一个接收两个参数并具有void返回类型的函数指针。那ret就是void。返回类型为 void 的函数不返回任何内容。当然,您无法读取调用的返回值,(*func)()因为您说没有返回值。

即使读取返回值的分支不会被执行,它仍然需要编译并通过静态类型检查。这里的基本问题是调用*func()是在编译时处理的,并且是编译时静态类型检查。

这个Stack Overflow问题涵盖了与您完全相同的问题,并且接受的答案显示了如何处理该问题

于 2012-05-14T19:57:08.533 回答
1

我假设“arg1”、“arg2”和“ret”都是模板参数。鉴于此,即使代码会将您带到运行时路径(*func)(ar1, ar2),编译器仍然必须编译ret val = (*func)(ar1, ar2);,这对于返回 void 的函数没有意义。我认为这是给你的错误。你能给我们提供更多的代码吗?

编辑:好的,既然我看到了您要执行的操作,您将需要这样的东西来执行 void 和 non-void 函数,每个函数具有不同的行为:

int foo(){ return 5; }
void bar(){}

struct executor
{
    template <typename T>
    void exec( T (*func)())
    {
        T ret = (*func)();
        cout << "Non-void function called, returned " << ret << endl;
    }

    void exec( void (*func)())
    {
        (*func)();
        cout << "void function called" << endl;
    }
};

int main()
{

    executor ex;
    ex.exec(foo);
    ex.exec(bar);

    return 0;
}
于 2012-05-14T19:59:47.977 回答