我可以在“太少的初始化器”上造成编译错误吗?
-
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) 8.5.1.7指出以下内容:
如果列表中的初始化器比聚合中的成员少,则每个成员未明确初始化的成员应为默认情况下(8.5)。 [示例:struct s {int a; char* b; int c; }; s ss = {1,“ asdf”};用1个ss.b初始化ss.a,带有“ ASDF”,SS.C具有int()表达式的值,即0。
简而言之,您问题的答案是否定的。
根据 MSDN, ,如果指定了较少的初始化器,则其余元素以0初始化,因此代码仍应起作用。
不隶属于 StackOverflow