Visual C++ 初始化与 gcc 和 clang 不一致

Visual C++ initialization inconsistence with gcc and clang

下面这段代码prints 0 compiled with vc++ and prints 1 compiled with g++ or clang++:

#include <iostream>
#include <vector>

struct S
{
    S() = default;

    std::vector<int> v{0};        
};

int main()
{
    std::vector<S> s{{}};

    std::cout << s.front().v.size() << std::endl;
}

是否是 vc++ 中的错误?

如果提供了用户定义的构造函数(S() {}; 而不是 S() = default;vc++ starts to print 1, too

这不是答案,而是需要代码的评论。

我认为以下更清楚地说明了编译器的差异:

#include <iostream>
#include <vector>

struct S
{
    S() = default;

    std::vector<int> v = std::vector<int>(13);
};

int main()
{
    std::vector<S> s{{}};
    std::cout << s.front().v.size() << std::endl;
}

此处 g++ MinGW 5.1.0 报告 13 个项目,而 MSVC 2015 更新 2 报告 0 个项目。

即g++ 使用 class 中指定的初始值设定项,而 MSVC 使用 s 声明中指定的初始值设定项。对我来说,这看起来像是 g++ 的问题。但我不确定:唯一确定的是两者不可能都是对的。

在阅读标准 (C++11 n3485) 时,12.6.2/9 指出:

If a given non-static data member has both a brace-or-equal-initializer and a mem-initializer, the initialization specified by the mem-initializer is performed, and the non-static data member’s brace-or-equal-initializer is ignored.

所以问题就变成了default,即隐式定义的构造函数是否包含mem-initializer

12.1/6 节指出:

The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement.

这意味着隐式生成的(默认)构造函数没有 mem-initializer 并且确实应该使用 in-class 初始化程序(上面引用中的 brace-or-equal-initializer)。

MSVC 在这里是错误的(这并不奇怪,真的)。