2012-02-29 9 views
0

私はCで実装されたバリアント型のC++ 11ラッパーを扱っています。バリアント型はint、float、stringのような一般的なデータ型をサポートしますが、タプルもサポートします。私はフォームの基本的な型のコンバータを持っています...バリアントの配列をstd :: tupleに変換する

template<typename T> 
T convert_to(const Variant &var); 

...しかし、私はstd :: tupleへの変換に苦労しています。

基本となるC APIは、バリアントの配列を返すことによってタプルを分割することができます。

int get_tuple(Variant var, Variant **argv, int *argc); 

は、今私は、私は手動でタプルの各サイズのテンプレートを作成することができます認識し、私はタプルの任意のサイズを扱うことができる可変引数解決策を探しています:それは次のようになります。これにアプローチする方法についてのヒント?

私が実際に取り組もうとしていることは、Erlang NIF APIです。

+3

このタプルの概念は、簡単に 'std :: tuple'にマップされますか?そのアリティは、コンパイル時ではなく、実行時に利用できるようです。もし既知の場合と小さい場合の可能な数の場合は、あなたはこれを抜け出すことができますが、その型に対する最終的なインタフェースは 'std :: tuple'のようには見えません。 –

+0

私は、バリアントタプルの要素がstd :: tupleの要素と一致しない場合、例外をスローするつもりです。 – goertzenator

答えて

2

C++ 11を使用しているので(テンプレートパラメータのタプルタイプを知っているので)、バリデーショナルテンプレートをうまく使うことができます。 *

array_to_tupleは一つの要素の1コピーする
template <class ... Ts> 
std::tuple<Ts...> convert_to(const Variant& v) 
{ 
    Variant tmp_array[std::tuple_size<std::tuple<Ts...>>::value]; 
    get_tuple(v, tmp_array, sizeof(tmp_array)/sizeof(tmp_array[0])); 
    std::tuple<Ts...> ret; 
    array_to_tuple(ret, tmp_array); 
    return ret; 
} 

ような何か:これが動作することができます

template <class ... Ts> 
struct array_to_tupler 
{ 
    template <int I> 
    static void do_it(std::tuple<Ts...> &t, Variant* vs) 
    { 
    std::get<I-1>(t) = convert_to<decltype(std::get<I-1>(t))>(vs[I-1]); 
    do_it<I-1>(t, vs); 
    } 
    template <> 
    static void do_it<0>(std::tuple<Ts...> &t, Variant* vs) 
    { 
    } 
}; 

template <int N, class ... Ts> 
void array_to_tuple(std::tuple<Ts...> &t, Variant (&vs)[N]) 
{ 
    array_to_tupler<Ts...>::do_it<N>(t, vs); 
} 

は希望を...

*)などconvert_toが簡単に呼び出し可能ではないことに注意してください。関数テンプレートにはできない部分的な特殊化が必要なので、クラステンプレートを使用して戻り型の特殊化を行うことをお勧めします。

+0

テンプレートクラス内で関数の特殊化を行うことは不正ですが、それを裏返すと機能します(array_to_tuplerはint Nでテンプレート化され、do_itはTsでテンプレート化されます...)。正しい方向に私を指してくれてありがとう。 – goertzenator

関連する問題