5

foo()ライブラリ コンテキストで提供されている関数があります。ライブラリは、この関数のいくつかのオーバーロードを次のように定義します。

char foo(float x, int y);
short foo(double x, char y);

(上記の引数/結果の型を作成しました。要点は、引数の型とオーバーロードの対応する戻り値の型の間に一般的な関係がないことです。)

アイデアは、ライブラリ ユーザーがfoo()必要に応じて独自のユーザー定義型のオーバーロードを追加できるということです。関数のオーバーロードは、これを非常に簡単に実現します。

Boost.Protofoo()で関数ファミリーを使用できるようにしたいと考えています。そのためには、テンプレート呼び出し演算子を使用して関数オブジェクトで上記をラップする必要があると思います。

struct foo_wrap
{
    template <typename A1, typename A2>
    result_type operator()(A1 a1, A2 a2) { return foo(a1, a2); }
};

問題は、 を定義する方法にありますresult_type。これは、C++11 とdecltype()末尾の関数の戻り値の型を使用すると簡単だと思いますが、C++03 のソリューションを探しています。したがって、foo_wrapTR1 スタイルの関数オブジェクトである必要があります。引数の型とresult_typeのコンパイル時関数として定義する方法を見つける必要があります。これは、戻り値の型だけでなく、TR1プロトコルが機能するためにも必要です。要するに:A1A2operator()result_of

  • 関数名と引数の型のセットを指定すると、関数の対応する戻り値の型を生成するメタプログラミング手法はありますか?
  • または、関数の複数のオーバーロードを汎用関数オブジェクトでラップするために使用できる別の手法はありますか?
4

1 に答える 1

4

そのための特性を手動でフィードできます。

template <typename A1, typename A2>
struct foo_wrap_result;

struct foo_wrap
{
    template <typename A1, typename A2>
    typename foo_wrap_result<A1, A2>::type
    operator()(A1 a1, A2 a2) const { return foo(a1, a2); }
};

特性の特殊化:

template <>
struct foo_wrap_result<float, int> { typedef char type; };

template <>
struct foo_wrap_result<double, char> { typedef short type; };
于 2014-12-20T00:07:47.730 に答える