次のようにコンパイル時に静的配列を定義できます。
const std::size_t size = 5;
unsigned int list[size] = { 1, 2, 3, 4, 5 };
質問1- さまざまな種類のメタプログラミング手法を使用して、コンパイル時にこれらの値を「プログラム的に」割り当てることは可能ですか?
質問2- 配列内のすべての値がいくつかを除いて同じであると仮定した場合、コンパイル時にプログラム的に値を選択的に割り当てることは可能ですか?
例えば:
const std::size_t size = 7;
unsigned int list[size] = { 0, 0, 2, 3, 0, 0, 0 };
- C++0xを使用したソリューションは歓迎します
- 配列は数百の要素を持つ非常に大きなものになる可能性がある
- 現時点では配列はPOD型のみで構成されます
- また、静的コンパイル時に準拠した方法で、配列のサイズが事前にわかっていると想定することもできます。
- ソリューションはC++でなければなりません(スクリプト、マクロ、PP、コード ジェネレーター ベースのソリューションは使用しないでください)
アップデート:Georg Fritzsche のソリューションは素晴らしいものですが、MSVC および Intel コンパイラでコンパイルするには少し作業が必要ですが、それでも問題に対する非常に興味深いアプローチです。
ベストアンサー1
最も近い方法は、C++0x 機能を使用して、可変長テンプレート引数リストからテンプレートのローカル配列またはメンバー配列を初期化することです。
もちろん、これはテンプレートのインスタンス化の最大深度によって制限されるため、実際にそれが顕著な違いを生むかどうかは、測定する必要があります。
例:
template<unsigned... args> struct ArrayHolder {
static const unsigned data[sizeof...(args)];
};
template<unsigned... args>
const unsigned ArrayHolder<args...>::data[sizeof...(args)] = { args... };
template<size_t N, template<size_t> class F, unsigned... args>
struct generate_array_impl {
typedef typename generate_array_impl<N-1, F, F<N>::value, args...>::result result;
};
template<template<size_t> class F, unsigned... args>
struct generate_array_impl<0, F, args...> {
typedef ArrayHolder<F<0>::value, args...> result;
};
template<size_t N, template<size_t> class F>
struct generate_array {
typedef typename generate_array_impl<N-1, F>::result result;
};
あなたの1..5
ケースでの使用法:
template<size_t index> struct MetaFunc {
enum { value = index + 1 };
};
void test() {
const size_t count = 5;
typedef generate_array<count, MetaFunc>::result A;
for (size_t i=0; i<count; ++i)
std::cout << A::data[i] << "\n";
}