1

フォーマットされていない fortran ファイルから 1 次元配列を読み取る this 関数があります。

template <typename T>
void Read1DArray(T* arr)
{
    unsigned pre, post;
    file.read((char*)&pre, PREPOST_DATA);

    for(unsigned n = 0; n < (pre/sizeof(T)); n++)
        file.read((char*)&arr[n], sizeof(T));

    file.read((char*)&post, PREPOST_DATA);
    if(pre!=post)
        std::cout << "Failed read fortran 1d array."<< std::endl;
}

私はこれを次のように呼びます:

float* new_array = new float[sizeof_fortran_array];
Read1DArray(new_array);

Read1DArray が「file」という名前の ifstream を含むクラスの一部であり、sizeof_fortran_array が既知であると仮定します。(そして、Fortran のフォーマットされていない書き込みにあまり慣れていない人のために、'pre' データは配列の長さをバイト単位で示し、'post' データは同じです)

私の問題は、float* または double* を使用してこの関数を呼び出したいシナリオがあることですが、これは実行時までわかりません。

現在、私がしているのは、読み取るデータ型のフラグを設定するだけで、配列を読み取るときに、次のようなコードを複製します。ここで、データ型は実行時に設定される文字列です。

if(datatype=="float")
    Read1DArray(my_float_ptr);
else 
    Read1DArray(my_double_ptr);

関数呼び出しを2つのタイプで複製する必要がないように、誰かがこれを書き直す方法を提案できますか? これらは、それを呼び出す必要がある唯一の 2 つのタイプですが、私はそれをかなりの回数呼び出す必要があり、この重複をいたるところに配置したくありません。

ありがとう

編集: call_any_of 関数でラップするという提案に応えて、これは十分ではありません。

if(datatype=="float")
{
    Read1DArray(my_float_ptr);
    Do_stuff(my_float_ptr);
}
else 
{
    Read1DArray(my_double_ptr);
    Do_stuff(my_double_ptr);
}

// More stuff happening in between  

if(datatype=="float")
{
    Read1DArray(my_float_ptr);
    Do_different_stuff(my_float_ptr);
}
else 
{
    Read1DArray(my_double_ptr);
    Do_different_stuff(my_double_ptr);
}
4

2 に答える 2

3

タイトルについて考えると、テンプレートのインスタンス化はコンパイル時に実行されるが、実行時にのみ利用可能な情報に基づいてディスパッチしたいという矛盾があることに気付くでしょう。実行時にテンプレートをインスタンス化できないため、それは不可能です。

あなたが取ったアプローチは実際には正しいものです。コンパイル時に両方のオプションをインスタンス化し、利用可能な情報を使用して実行時にどちらを使用するかを決定します。そうは言っても、あなたはあなたのデザインを考えたいと思うかもしれません.

そのランタイム値に基づいて、読み取りだけでなく処理も異なると思います。そのため、すべての処理を (おそらくテンプレート) 関数で型ごとにバインドifし、呼び出し階層をさらに上に移動することをお勧めします。


型に基づいてテンプレートの異なるインスタンス化にディスパッチする必要を回避する別のアプローチは、型の安全性の一部を失いvoid*、割り当てられたメモリとsize配列内の型のサイズを持つ引数を受け取る単一の関数を実装することです。これはより脆弱であり、データが読み取られた後に別の配列に対処しなければならないという全体的な問題を解決しないことに注意してください。したがって、このパスに従うことはお勧めしません。

于 2013-08-16T13:45:33.720 に答える