17

インスタンス化されている関数の戻り値の型をパラメーターとして取得するテンプレートを作成したいと思います。

たとえば、Resultテンプレート化されたクラスがあるとします。

template<type T>
class Result {
    T _result_value;
    T& operator=( T that );
    ~Result( );
}

このクラスにはいくつかの専門分野があります。デストラクタでは戻り値の型をログに記録し、operator=代入内ではエラー値をチェックしてアサートしたいと考えています。

理想的には、次のような定義ができるようにしたいと考えています。

#define RESULT Result< /* decltype magic for type of current function */ >

だから私はそれを使うことができました:

HFILE MyOpenFile( ... ) {
    RESULT result;
}

...これは と推定されResult<HFILE>ます。RESULTこれは簡単な例です。代わりに書くことResult<HFILE>は大したことではありませんが、現在の関数の戻り値の型を簡単に取得できないシナリオは他にもあります。

4

3 に答える 3

5

いいえ、「現在の関数」を参照する C++ には何もありません。最も近い__func__のは文字列リテラルです。したがって、 に渡すものは何もありませんdecltype

あなたがそれを必要とするわけではありませんauto

于 2012-11-08T10:41:22.430 に答える
4

型を推測するために参照できる、関数を表す専用のオブジェクトがメモリ内にないため、関数内からは不可能です。を介して、クラスで可能ですdecltype(*this)

于 2012-11-08T10:40:46.147 に答える
4

私が考えることができる最も移植性の高い方法は、次を使用することdecltypeです:

#define RESULT(func, ...) Result<decltype(func(__VA_ARGS__))>

int main(int argc, char **argv) {
    RESULT(main, argc, argv) result; // same as `Result<int> result;`
}

ただし、これにより、関数名とそれが取るすべての引数をRESULTマクロに渡す必要があります。現在の関数や渡された引数の識別子を取得するための移植可能な (そして多くの場合、コンパイラ固有でさえない) 方法がないため、これは避けられないと思います。オーバーロードのあいまいさのおかげで、引数は問題を渡しました。

ここにSSCCEがあります: http://ideone.com/cPTjjF

于 2012-11-08T10:42:26.830 に答える