8

次のように、最初の 10 個の素数を格納する配列があるとします。

const int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};

1 つの .cpp ファイルがある限り、これはすべて非常に問題なくシンプルです。ただし、複数の .cpp ファイルがある場合、この配列をどこに配置すればよいかわかりません。

明らかな解決策は次のとおりです。

// primes.h:
extern const int primes[10];

// primes.cpp:
extern const int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};

ただし、これの問題は、素数配列がコンパイル時の定数ではなくなったことです。x.cpp が素数 [k] を含むいくつかの重い計算を実行したいとします。コンパイル時定数は ka で、実際のメモリ ルックアップを実行する必要があります。私はそれが好きではありません。

では、次のようにこの配列をどこに配置すればよいでしょうか。

  1. バイナリで 1 回だけです (.cpp ファイルごとに 1 回ではありません)。
  2. array[SOME_CONSTANT] もコンパイル時の定数です

編集

これはどう?

inline int prime(int i) {
    static const int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
    return primes[i];
}

PS:上記の「明白な解決策」でさえ、書くのにかなりの時間がかかりました。どうやら const 変数にはデフォルトで内部リンクがあるようです。そのため、「extern」を primes.cpp ファイルに追加して機能させる必要がありました。

4

3 に答える 3

5

私はこれがうまくいくはずだと思います(Migiのテストで欠陥が明らかになった後、現在更新されています):

template <bool dummy>
struct primes_lut
{
    static const int values[];
};

template<bool dummy>
const int primes_lut<dummy>::values[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };

static auto& primes = primes_lut<true>::values;

(C++ では、より多くのテンプレートを使用しても解決できない問題はありません。)

別のアプローチ:

struct primes_lut { int values[10]; };
inline const primes_lut& primes_lut_provider(void)
{
    static const primes_lut values = { {2, 3, 5, 7, 11, 13, 17, 19, 23, 29} };
    return values;
}
static const int (&primes)[10] = primes_lut_provider().values;

最後に、定数の折りたたみを実装する最新のリンカーでは、これらのトリックは必要ありません。

于 2011-02-18T21:10:27.710 に答える
1

ヘッダー内で列挙型を使用できます。列挙型はコンパイル時定数であることが保証されており、(C ++ 0X列挙型クラスを使用しない限り)暗黙的に整数に変換されます。

于 2011-02-18T20:19:08.187 に答える
0
static const int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};

ヘッダーファイルで。これにより、実行可能ファイルが大きくなる可能性があります(各ソースファイルには独自の配列のコピーがあります)が、現在受け入れられている回答にも同じ問題が当てはまると思います.

于 2016-07-09T19:23:44.653 に答える