小编Lil*_*ste的帖子

测试抛出的特定异常类型,并且异常具有正确的属性

我想测试MyException在某种情况下抛出的东西.EXPECT_THROW这里很好.但我也想检查异常是否有特定的状态,例如e.msg() == "Cucumber overflow".

如何在GTest中实现最佳效果?

c++ unit-testing exception googletest

48
推荐指数
6
解决办法
4万
查看次数

C++标准是否允许使用const成员对POD对象进行零初始化?

我已经定义了一个POD,我计划将其用作不可变数据存储.为了实现这一点,我已经对其成员进行了限定const,并期望对实例进行值初始化(在某些情况下为零初始化).请考虑以下代码:

struct Foo
{
    const int value;
};

int main()
{
    Foo foo{ };

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试对此POD进行零初始化时,由于符合条件,我在Visual Studio(C3852)中遇到编译器错误.如果我删除限定符,代码编译正常.constFoo::value

确切的错误消息是:

错误C3852:'Foo :: value'类型为'const int':聚合初始化无法初始化此成员const成员不能默认初始化,除非它们的类型具有用户定义的默认构造函数

根据标准(草案n3337),§8.5/ 5(零初始化):

零初始化T类型的对象或引用意味着:

- 如果T是标量类型(3.9),则将对象设置为值0(零),作为整数常量表达式,转换为T;

- 如果T是(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;

- 如果T是(可能是cv限定的)联合类型,则对象的第一个非静态命名数据成员为零初始化,并且填充初始化为零位;

- 如果T是数组类型,则每个元素都是零初始化的;

- 如果T是引用类型,则不执行初始化.

和§8.5/ 6(默认初始化):

默认初始化T类型的对象意味着:

- 如果T是一个(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);

- 如果T是数组类型,则每个元素都是默认初始化的;

- 否则,不执行初始化.如果程序要求对const限定类型T的对象进行默认初始化,则T应为具有用户提供的默认构造函数的类类型.

和§8.5/ 7(值初始化):

对值类型T的对象进行值初始化意味着:

- 如果T是具有用户提供的构造函数(12.1)的(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);

- 如果T是一个(可能是cv限定的)非联合类类型而没有用户提供的构造函数,那么该对象是零初始化的,如果T的隐式声明的默认构造函数是非平凡的,则调用该构造函数.

- 如果T是数组类型,则每个元素都是值初始化的;

- 否则,对象被零初始化.

我对标准的阅读使我相信我的POD应该是零初始化的; 没有默认初始化.我是否误解了标准中描述的初始化过程?

编辑:考虑到接受的答案和相关评论中提供的详细信息,这看起来像VS实现中的潜在错误(即,实现可能基于标准的过时版本).我已经创建了一个Microsoft Connect票据来跟踪它,可以在这里找到:

https://connect.microsoft.com/VisualStudio/feedback/details/846222/c-compiler-uses-incorrect-initialization-scheme-for-certain-objects

c++ language-lawyer c++11

13
推荐指数
1
解决办法
779
查看次数