2011-06-20 2 views
2

関数の戻り値の型(関数ポインタの方が良い)が何であるかを調べる方法はありますか?テンプレートのインスタンス化時に関数の戻り値の型を決定するにはどうすればよいですか?

私はvoid関数ポインタを使用すると壊れますが、他の戻り値の型ではうまく機能する次のコードがあります。 gcc 4.5のvoid関数ポインタを使用するとエラーが発生します。

error: void value not ignored as it ought to be

これは意味があります。関数ポインタが何かを返すかどうかを確認し、結果を取得して返す必要があることは明らかです。

template <class F,typename R> class Instruction 
{ 
    protected: 
    F (func); 
    R result; 

    public: 

    template <typename T> 
    Instruction(T const& f) 
    { 
    func = &f; 
    }; 

    template <typename A> void execute(A const& a) 
    { 
    result = (func)(a); 
    }; 
    template <typename A> void execute(A const& a,A const& b) 
    { 
    result = (func)(a,b); 
    }; 
    template <typename A> void execute(A const& a,A const& b,A const& c) 
    { 
    result = (func)(a,b,c); 
    }; 
    R get_result() 
    { 
    return result; 
    }; 
}; 

通常、何かほとんどが算術演算を行う関数へのポインタを使用し、void関数以外のインスタンス化では任意の戻り値型を処理できます。私は次のようにインスタンス化しようとしました:

 Instruction<ptr2func2,void> foo(bar); 
    Instruction<ptr2func2,(*void)> foo(bar); 

しかしどちらの場合も失敗します。

インスタンス化時の2番目のテンプレート引数は、戻り値の型を定義するために使用されます。

+0

、あなただけの 'R'をチェックする必要があります。 – ikegami

答えて

3

template partial specialization voidにしてみてください。それは簡単になるはずですが、私はどのようにわかりません。
+0

それは完璧に働いてくれてありがとう! それでは、基本的に私は特殊化のためのテンプレート引数をvoidだけでオーバーロードしますか?ありがとう、私はこれを前に見たはずだった! :) –

+0

ヒント:C++では 'void '式(he he)を'返す'ことができるので、クラスのメンバ変数の部分だけを特殊化する必要があります。この部分は基本クラスとして、またはメンバーとして取り出すことができます。 –

1

Boost::FunctionTypesを使用して、関数型を分解して戻り値または引数型にアクセスできるメタ関数を提供することができます。

1

C++ 0xでは、decltypeとすることができます。しかし、C++ 03では、関数オブジェクトはresult_type typedefを持ち、関数ポインタはそれらにテンプレート減算を適用できます。あなたは、関数の戻り値の型をチェックする必要はありません

template <class F> class Instruction<F, void> 
{ 
    protected: 
    F (func); 

    public: 

    template <typename T> 
    Instruction(T const& f) 
    { 
    func = &f; 
    }; 

    template <typename A> void execute(A const& a) 
    { 
    (func)(a); 
    }; 
    template <typename A> void execute(A const& a,A const& b) 
    { 
    (func)(a,b); 
    }; 
    template <typename A> void execute(A const& a,A const& b,A const& c) 
    { 
    (func)(a,b,c); 
    }; 
}; 
関連する問題