「イニシャルが少なすぎる」でコンパイルエラーを引き起こすことはできますか?
-
01-10-2019 - |
質問
集約イニシャルイザーを使用して、ユニットテストのために静的データのブロックを設定しています。
予想される要素の数として配列サイズを使用したいのですが、初期剤が少なすぎると失敗する可能性があります。
my_struct_type expected[14] =
{
{ 1.234, 0, 'c' },
{ 3.141, 1, 'z' },
{ 2.718, 0, 'a' }
};
これにより、Visual Studio 2008ではコンパイラエラーが発生しません。
そのように使用できるようにしたい:
const unsigned expected_size = sizeof(expected) / sizeof(my_struct_type);
BOOST_CHECK_EQUAL(points.size(), expected_size);
for( int i = 0; i < expected_size; i++ )
{
BOOST_CHECK_EQUAL(points[i].value, expected[i].value);
BOOST_CHECK_EQUAL(points[i].count, expected[i].count);
BOOST_CHECK_EQUAL(points[i].sym, expected[i].sym);
}
しかし、私は14ポイントのコンパイル時間保証がないため、これは 配列の終わり 提供された値の終了およびデフォルトの象徴化された値に。
コンパイル時に集計アレイ初期剤の数をどうにか強制することはできますか?
解決
最初:これについては警告があるかもしれません。最高の警告レベルでコンパイルを試してみましたか?
次に、どの値を計算し、どの値をリテラルに交換した場合は、コンパイル時間エラーを上げることができます。
my_struct_type my_array[] = // <== note the empty []
{
{ 1.234, 0, 'c' },
{ 3.141, 1, 'z' },
{ 2.718, 0, 'a' }
};
BOOST_STATIC_ASSERT( sizeof(my_array)/sizeof(my_array[0]) == 14 );
他のヒント
実際には、コンパイラが自分自身を初期化しなかったアレイのすべての要素をデフォルトで挿入するため、実際には配列の端から実行されません。
特定の数の設定された初期装置があることを確認しようとしている場合、それを行う方法がわかりません。
配列があなたが持っているアイテムの数であることを確認するだけの場合:
my_struct_type expected[] =
{
{ 1.234, 0, 'c' },
{ 3.141, 1, 'z' },
{ 2.718, 0, 'a' }
};
トリックをします。次に、使用してください sizeof(expected) / sizeof(expected[0])
配列要素の総数を取得します。
ブースト以外の答えのために…
変更して、初期化要件を追加できます my_struct_type
.
template< typename T >
struct must_be_initialized {
T value;
must_be_initialized( T const &v ) : value( v ) {}
// no default constructor!
operator T& () { return value; }
operator T const& () const { return value; }
};
struct my_struct_type {
must_be_initialized< double > f;
int i;
char c;
};
my_struct_type expected[14] =
{
{ 1.234, 0, 'c' },
{ 3.141, 1, 'z' },
{ 2.718, 0, 'a' }
// error: no default constructor exists
};
my_struct_type
まだ集計ですが、ポッドではありません。
ISO/IEC 14882(初版1998-09-01)のp。 8.5.1.7は次のように述べています。
リスト内の初期剤が集合体にいるメンバーよりも少ない場合、明示的に初期化されていない各メンバーはデフォルトの開始(8.5)でなければなりません。 [例:struct s {int a; char* b; int c; }; s ss = {1、 "asdf"}; ss.aを1、ss.bを「asdf」、およびss.cでss.aを初期化します。
簡単に言えば、あなたの質問に対する答えはノーです。
による MSDN, 、より少ない初期剤が指定されている場合、残りの要素は0で初期化されるため、それでもコードは動作するはずです。