5

コンパイル時の定数パラメーターに応じて、次のような同じコードを作成する必要があります。

map["text 0"] = vec[0];
map["text 1"] = vec[1];
...
map["text n"] = vec[n];

n問題は、コードを書いているときにわからないことです。テンプレート パラメーターとして受け取ります。明らかな解決策は、1 つ"text k"のループを使用し、ループ内で を生成して を使用するvec[k]ことですが、コンパイル時に実行する必要がある場合、実行時のオーバーヘッドが発生します。別の解決策は、関数をさまざまなN値に特化することですが、この方法では同じコードを何度も手作業で記述する必要があり、テンプレートにする理由はありません。

同様のことを N 回繰り返すことができるいくつかのスマート マクロ (BOOST_PP_REPEATマクロ ファミリなど) があることは知っていますが、特定の問題に対する 1 つの解決策が見つかりません。

この問題の解決策はありますか?

4

3 に答える 3

4

非常に厳しいパフォーマンスの制約がない限り、実行時のオーバーヘッドについて心配する必要はありません。いずれにせよ、挿入は実行時に実行され、挿入時間は文字列内の文字を変更するのに必要な時間の大半を占めます。

さらに、マクロはデバッグや保守が難しいため、可能であれば避けてください。ここでは、単純なループを展開することをお勧めします。

std::string s = "text 0";
std::map<std::string, int> m;
for (int i = 0; i < N; i++)
{
    m[s] = vec[i];
    s[5] = '1' + i; // This is going to be the run-time overhead...
}

数値が より大きくなった場合、C++11 では整数を文字列に変換する関数を9使用できます。to_string()

std::string const s = "text ";
std::map<std::string, int> m;
for (int i = 0; i < N; i++)
{
    m[s + std::to_string(i)] = vec[i];
}

パフォーマンスが問題になる場合は、マクロに基づくよりハードコアなアプローチを試すことができます。ただし、測定値が大きなオーバーヘッドを示さない場合は、単純さと明快さを優先し、単純なループを展開します。

于 2013-03-29T09:17:11.517 に答える
0

私は以下がうまくいくはずだと信じています:

#include <boost/preprocessor.hpp> 
//... or just the required sub-headers

// Will generate code for 0, 1, ... (N_END - 1)
#define N_END 10

#define ONE_ASSIGNMENT(maZ, maIter, maData) \
    if (maIter <= n) map["text " BOOST_PP_STRINGIZE(maIter)] = vec[maIter];

BOOST_PP_REPEAT(N_END, ONE_ASSIGNMENT, %%) //this generates the code

#undef ONE_ASSIGNMENT
#undef N_END

if()はリテラルをテンプレート パラメーター ( n) と比較するため、salt に値するオプティマイザーはこれからブランチレス コードを生成することに注意してください。

%%「この値は使用されません」として使用します。これは引数に渡されるmaDataので、実際に渡すと便利なもの ( など"text ") がある場合は、代わりにそれを行うことができます。

于 2013-03-29T09:06:50.550 に答える
0

繰り返しは私には問題に思えませんが、コンパイル時の int から string への変換とそれに続く連結は問題になります。繰り返しの問題は、次の手法で解決できます (テストされていません)。

template<k,l> struct fill_vector {
    static void doIt (... & vec) {
        vec [INT_TO_TEXT (k)] = k;
        fill_vector<k+1,l-1>::doIt (vec);
    }
};

template<k> struct fill_vector<k,0> {
    static void doIt (... & vec) {
        vec [INT_TO_TEXT (k)] = k;
    }
};

//...

fill_vector<0,n>::doIt (vec);

多分誰かが実装方法を考えているINT_TO_TEXT

于 2013-03-29T09:33:08.300 に答える