汎用関数オブジェクトのためのパラメータ
こんなのあったら便利だなーって感じで作り始めてみました。
今やろうとしているのは、汎用関数オブジェクトのためのインターフェースクラスを用意して、そこから任意の数のパラメータを渡して呼び出せるようにすること。
class IFunction { public: virtual IParameter Invoke(Array<IParameter> parameters) = 0; }; int A(int a, int b) { return a + b; } void main() { // 関数オブジェクトを生成する IFunction function = MakeFunction<int (int&)>(&A); // パラメータを生成する Array<IParameter> parameters = MakeArray<IParameter>(2); parameters[0] = MakeParameter<int>(10); parameters[1] = MakeParameter<int>(20); // 呼び出し IParameter resultParameter = function->Invoke(parameters); // 戻り値の取り出し int result; // TryGetParameter<int>() は、戻り値が int にキャスト出来るのであれば // result に値を入れて true を返す。 if (TryGetParameter<int>(resultParameter, result)) { ... } // GetParameter<std::string>() は、 // 戻り値が std::string にキャスト出来なければ例外を投げる result = GetParameter<std::string>(resultParameter); // ↑ここで例外が投げられる }
こんな感じで使えるようにしたいわけです。
IFunction の実装はそんなに難しくなくて、IParameter を boost::shared_ptr
typedef boost::shared_ptr<void> IParameter; template<class Signature> class Function; template<class TResult, TArg0, TArg1> class Function<TResult (TArg0, TArg1)> : public IFunction { public: TResult operator()(TArg0 arg0, TArg1 arg1) { // boost::function っぽい実装を入れる } virtual IParameter Invoke(Array<IParameter> parameters) { // operator()() を呼び出すだけ boost::shared_ptr<TResult>(new TResult( (*this)(*boost::static_pointer_cast<TArg0>(parameters[0]), *boost::static_pointer_cast<TArg1>(parameters[1])))); } };
こんな感じで書けます。
問題は IParameter の実装です。
とりあえず↑では boost::shared_ptr
基本型や仮想テーブルの持っていないクラスは仕方ないとしても、dynamic_cast<> が有効なクラスには型安全でやりたいところです。
この実装をどうするかというのをちょっと考えてみることにします。
# 現在試行錯誤中なのですが、煮詰まってる状態だったりw