2011-07-04 9 views
2

私は多種多様なC++関数を持っています。これはほぼ20種類の異なる型で呼び出すことができます。boost.pythonを使ってC++の多型関数をエクスポートするスマートな方法

私はこのような何かやっているのpythonためにそれを公開するために:

BOOST_PYTHON_MODULE(module_foo) 
{ 
    def("foo", foo<orignalFunctionNamespace::type1>); 
    def("foo", foo<orignalFunctionNamespace::type2>); 
    def("foo", foo<orignalFunctionNamespace::type3>); 
    def("foo", foo<orignalFunctionNamespace::type4>); 
    def("foo", foo<orignalFunctionNamespace::type5>); 
    def("foo", foo<orignalFunctionNamespace::type6>); 
    def("foo", foo<orignalFunctionNamespace::type7>); 
    ... 
    ... 
    ... 
    def("foo", foo<orignalFunctionNamespace::typeN>); 
} 

#include originalFunctionNamespace.hpp 

template<class T> 
    T foo(T x) 
    { 
     return orignalFunctionNamespace::foo(x); 
    } 

をが、その後のpythonからそれらを呼び出すために、私は、彼らがサポートする各タイプに機能を特化する必要が

これは機能しますが、私はそれを行うよりスマートな方法がなければならないと考えることをやめることはできません。私は多くの多くの機能のためにそれをやらなければならないので、物事は大きくて超反復しています。 提案がありますか?

+1

これはポリモフィズムではないようですが、関数のオーバーロードだけです。 – interjay

+1

本当に良い方法はありませんが、プリプロセッサを使って各行を短くし、 "using namespace originalFunctionNamespace;"それらをさらに短縮する。それは繰り返しを解決するのではなく、少なくともあなたに多くのテキストを保存します。 – Nobody

+0

@interjay関数は入力として多くの型を受け取ることができ、それに応じてさまざまな型を出力します。 "異なるタイプの値に評価されるか、または異なるタイプの値に適用される関数は、多形関数として知られています。"右? –

答えて

0

私はタイプリストマジックの可能性があります。あなたは新しい標準へのアクセス権を持っていない場合は、次のことができ

template <typename ArgType> 
void def_foo_overloads() 
{ 
    def("foo", foo<ArgType>); 
    // last type in list 
} 
template <typename ArgType, typename... MoreArgTypes> 
void def_foo_overloads() 
{ 
    def("foo", foo<ArgType>); 
    def_foo_overloads(MoreArgTypes...); 
} 

// use it like: 
def_foo_overloads<orignalFunctionNamespace::type1, 
        orignalFunctionNamespace::type2, 
        ... 
        orignalFunctionNamespace::typeN>(); 

あなたが使っている(または使用することができます)もし新しいC++ 0xの標準、あなたはこのような何かを書くことができます古い再帰タイプリストを使用して同等のことを行います。

+0

または: 'template void def_overloads(){std :: initializer_list {(def(" foo "、foo )、void()、0)...}; } ' –

+0

これはとてもきれいです! – Useless

+1

'std :: initializer_list 'のどちらにも該当しません。新しいリスト初期化構文を使用するすべての構成では、パラメータの評価の順序が保証されます。コンストラクタ呼び出し(唯一の保証は通常通りコンストラクタの本体に入る前のシーケンスポイントです)。だから'std :: pair (++ i、++ i)'は悪いですが、 'std :: pair {++ i、++ i}'は問題ありません。 'std :: initializer'は、任意の数の引数を受け入れることができるため、ここで使用されます。私は個人的には、可変のコンストラクタを持つ空の型を使います。 –

関連する問題