0

私は4種類のインデックスを持つデータベースを持っています。各索引タイプにはソート順があります。つまり、静的インデックス型を知っている場合は、そのインデックス内のオブジェクトをソートするための正しいファンクタが1つあります。また、インデックス型を知った直後に、つまりコンパイル時に静的にも知られています。C++ランタイム条件付き型情報の転送

データベースには、どのインデックスを話すかを決定するランタイムスイッチステートメントが含まれています。私はその関数がインデックス(イテレータ、ほとんど)からランタイム情報を返すだけでなく、使用する静的なオーダータイプも返すようにしたいと思います。

意図を示すために、ここにいくつかの擬似コードを示します。これはそのままでは機能しません...テンプレートの特殊化を使用してgetLookupInfo(戻り型の型はポリモーフィック)を書くことができます。注:私は仮想を使用したくありません。

template <typename Iterator, typename Order> 
struct LookupInfo { 
    typedef Order order; 
    uint64_t cost; 
    Iterator it1, it2, it3, it4; 
}; 

LookupInfo Database::getLookupInfo(LookupData data) 
{ 
    if (data == ....) { 
    return LookupInfo<Iterator1, Order1>(); 
    } 
    return LookupInfo<Iterator2, Order2>(); 
} 

some_function(LookupInfo lookup_info) { 
    vector<Record> records(lookup_info.begin(), lookup_info.end()); 
    sort(records.begin(), records.end(), lookup_info::order()); 
} 

これはまったく可能ですか?

+0

'getLookupInfo'がどのように動作するのか不思議です。私はそれがどのように呼び出されるのか見ていない。 return文は戻り値の型と一致しません。つまり、多型またはテンプレートの特殊化が必要です。 – AndyG

+0

Andy - はい - それで私はループを閉じることができません。コードスニペットは機能しません。これは、私が何をしたいのかを示すためのものです。そして、あなたは正しいです、そのトリックはどういうわけか、getLookupInfoの戻り値の型を毎回別の型に戻すようにしています。私はバーチャルを望んでいないので、私はテンプレートの専門を使用したいと思います。しかし、IMHOでも厄介です。私の質問の要点は、おそらく:どのように私はテンプレートの専門化を使用してgetLookupInfoを書くのですか? – Frank

+0

トリックはすべてを型に変えることです...どのようにして呼び出すかの疑似コードを私に与えると助けになるかもしれません。 – AndyG

答えて

0

getLookupInfo - > some_functionシーケンスを1つのディスパッチシーケンスにまとめることで、これを行うことができます。 、私はこれをスキップすることはできません、私は下に議論する理由のために(限り、それを呼び出すためにヘルパーファンクタを導入し、

template<typename LookupInfo> 
void some_function(LookupInfo lookup) 
{ 
    vector<Record> records(lookup_info.begin(), lookup_info.end()); 
    sort(records.begin(), records.end(), lookup_info::order()); 
} 

次へ:まず、それはテンプレート関数であるという事実を反映してsome_functionのあなたの定義を修正することができます私はしたい):

template<typename LookupInfo> 
struct some_functor 
{ 
    void operator()(LookupInfo lookup_info) 
    { 
     some_function<LookupInfo>(lookup_info); 
    } 
}; 

ディスパッチトリックのために今。上記のごgetLookupInfo機能を忘れて、代わりに定義します。

template<template <class L> class F> 
void dispatchLookupInfo(int data) 
{ 
    if (data == 0) { 
    auto lookup = LookupInfo<Iterator1, Order1>(); 
    F<LookupInfo<Iterator1, Order1>> fn; 
    fn(lookup); 
    } 
    else { 
    auto lookup = LookupInfo<Iterator2, Order2>(); 
    F<LookupInfo<Iterator2, Order2>> fn; 
    fn(lookup); 
    } 
} 

注ここで私はあなたはそれがあるかもしれないと述べたようdataがint型であることをふりをしています。したがって、LookupInfoを取得してから別々に関数を呼び出すのではなく、一度に実行します。ここでは、dispatchLookupInfoはテンプレートテンプレートパラメータを取ります。したがって、任意の関数を特殊化できます。これはヘルパーファンクタを必要とする私の要点に戻ります。テンプレートテンプレートパラメータとして(クラステンプレートではなく)関数テンプレートを渡す方法を見つけることができませんでした。しかし、それは私がそれはバーチャルコールに関与しないというあなたの要件を満たすと信じているようにclunky。

dispatchLookupInfo<some_functor>(0); 
関連する問題