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

これが失敗するテンプレートのインスタンス化では、2 つの引数を受け取り、戻り値の型funcを持つ関数ポインターです。voidつまりretですvoid。戻り値の型が void の関数は何も返しません。(*func)()当然、戻り値がないと言ったので、 の呼び出しの戻り値を読み取ることはできません。

戻り値を読み取るブランチは実行されませんが、コンパイルして静的型チェックに合格する必要があります。ここでの根本的な問題は、 への呼び出しが*func()コンパイル時に処理され、コンパイル時の静的型チェックの対象になることです。

このスタックオーバーフローの質問はあなたとまったく同じ問題をカバーしており、受け入れられた回答は問題の対処方法を示しています

于 2012-05-14T19:57:08.533 に答える
1

「arg1」、「arg2」、および「ret」はすべてテンプレート パラメーターであると想定しています。それを考えると、コードが実行時のパスを に移動したとしても(*func)(ar1, ar2)、コンパイラは をコンパイルする必要ret val = (*func)(ar1, ar2);があります。これによりエラーが発生していると思います。あなたのコードをもう少し提供してもらえますか?

編集:あなたがやろうとしていることがわかったので、それぞれ異なる動作で、void および非 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 に答える