C++ 入门第 5 次练习 7.52

C++ primer 5th exercise 7.52

运动
使用第 2.6.1 节(第 72 页)中的 Sales_data 的第一个版本, 解释下面的初始化。找出并解决任何问题。

我的代码:

#include <iostream>
#include <string>
using namespace std;

struct Sales_data
{
    string bookNo;
    unsigned sold_units = 0;
    double revenue = 0.0;
};

int main()
{
    Sales_data item = { "978-1234567",25,15.99 };
    cout << item.bookNo << ' ' << item.sold_units << ' ' << item.revenue << endl;
    system("pause");
}

我首先想到编译器会给我一个错误,因为有 in-class 初始值来防止“Sales_data”成为聚合 class。但事实并非如此。

在运行代码之后,我认为编译器使用初始化列表构造一个临时对象,将临时对象复制到“item”,最后销毁临时对象。

我的问题是:是否因为我在 Visual Studio 2017 年编码,所以编译器没有向我发送错误?上面的代码发生了什么。

你的困惑是由于初始化器和初始化器列表的使用在 C++98、C++11 和 C++14 标准之间发生了显着变化。

根据 C++98(不允许使用 in-class 初始化器)或 C++11(不允许用大括号括起来的初始化器列表),您显示的代码格式错误, 但根据 C++14(或更高版本)是可以接受的。

Visual Studio 2017 中的 MSVC 编译器默认使用 C++14 标准。如果你想 'more compatible' 使用你正在使用的 Primer,你可以明确地将它设置为使用 C++11 标准(IIRC——该选项已在 VS 2019 中删除)。 Select 您项目的“属性 → C/C++ → 语言 → C++ 语言标准”或添加 /std:c++11 命令行开关。

此外,为了严格(呃)遵守 selected 语言标准,还建议 select“一致性模式”(也在“属性”中 → C/C++ → 语言”,或通过 /permissive- 开关