2016-03-20 3 views
1

のうち、constの配列を構築することは、私はクラスでプライベートconstexprのを次している引数のために仮定しますconstexprの

static constexpr uint16_t square_it(uint16_t x) 
{ 
    return std::pow(x, 2); 
} 

その後、私は255までの整数のため、これらの値の静的定数配列を構築したいです上記constexprの使用して、同じクラスの同じセクション:

static const uint16_t array_of_squares[256] = 
{ 
    //something 
}; 

を私は、可能な場合は、配列はコンパイル時ではなく、実行時に構築することにしたいと思います。私は最初の問題は、constexprでstd :: powのような式を使用することは、ドメインエラーを返すことができるので、有効なISO C++(arm-gccによって許可されていますか?私が使用したい実際の式は、std :: expを含むやや複雑な関数です。

小さなマイクロプロセッサであるCortex M4用にコンパイルしているので、私はstdライブラリをあまり利用できません。

プリプロセッサマクロを使用すると、より適切な方法がありますか?私は、外部Pythonスクリプトのようなものを、開発中に変更する必要があるたびにテーブルを計算し、それを貼り付けることを避けたいと思っています。

+2

外部のPythonスクリプトでテーブルを計算し、ビルドで直接使用できるC++ファイルを作成します。コピー/貼り付けは不要です。 –

答えて

1

問題は、ライブラリ関数は一般にconstexprとマークされていません。

ここで最も適切な回避策は、std::expを使用する必要がある場合は、コンパイル時に実行できる独自の実装を作成することです。コンパイル時に実行されることになっている場合は、おそらくそれを最適化する必要はなく、正確で適度に効率的である必要があります。

誰かがそれを行う方法について質問しましたhereかなり前です。そこからアイデアを再利用し、C++ 11でconstexpr関数として書き直すことができますが、forループを避けるためにリファクタリングする必要があります。 C++では、リファクタリングが少なくて済むでしょう。

テンプレートを使用して厳密にやってみることもできますが、それはもっと苦労します。doubleはテンプレートパラメータにできないので、もっと複雑になります。

1

どうやってこのようなことができますか?

constexpr uint16_t square_it(uint16_t v) { return v*v; } 

template <size_t N, class = std::make_index_sequence<N>> 
struct gen_table; 

template <size_t N, size_t... Is> 
struct gen_table<N, std::index_sequence<Is...>> { 
    static const uint16_t values[N] = {square_it(Is)...}; 
}; 

constexpr auto&& array_of_squares = gen_table<256>::values; 

マイクロプロセッサがこの種の操作をサポートしているかどうかはわかりません。標準ライブラリにはmake_index_sequenceが含まれていない可能性がありますが(SOで実装されていても)、テンプレートインスタンス化に多大なメモリが必要になることがあります。しかし、少なくともそれはどこかで動作するものです。

関連する問題