为啥具有默认参数 std::initializer_list 的 ctor 不可用(VS2019)?

Posted

技术标签:

【中文标题】为啥具有默认参数 std::initializer_list 的 ctor 不可用(VS2019)?【英文标题】:Why is ctor with default argument std::initializer_list unavailable (VS2019)?为什么具有默认参数 std::initializer_list 的 ctor 不可用(VS2019)? 【发布时间】:2020-12-10 22:48:22 【问题描述】:

我不太明白为什么这段代码不能在 Visual Studio 2019 (16.8.3) 上编译:

#include <initializer_list>

struct Foo

    Foo(std::initializer_list<int> = );
;

int main()

    Foo f;


Foo::Foo(std::initializer_list<int>) 

它给了我这个错误:

C2512:“Foo”:没有合适的默认构造函数可用

这是一个编译器错误还是我在这里遗漏了什么? 请注意,我已经检查过,这确实在 GCC 10.1 上编译

如果将构造函数的前向声明更改为立即定义,则代码编译不会出错:

#include <initializer_list>

struct Foo

    Foo(std::initializer_list<int> = ) 
;

int main()

    Foo f;

【问题讨论】:

嗯,这很奇怪。在 VS-2017 上编译正常吗? 确保您的项目设置使用 c++17 或最新版本,vc 默认为 c++14,即使这样,问题也比最近的语言变体多得多。 在 VS 16.8.3 (19.28.29335) 中为我工作。检查您是否正在编译您认为正在编译的文件。 好的,对不起,我正在编译的代码有一个 ctor 的前向声明,而我最初发布的代码有一个空的 ctor 定义(在这种情况下应该无关紧要)。你能检查一下编辑后的版本是否编译了吗? 现在没有了。 【参考方案1】:

这里有一个编译器错误。

它不应该仅仅因为构造函数的定义在同一个翻译单元中不可用而导致编译失败(在另一个翻译单元中提供它,或者甚至在main 下提供它,不允许程序构建)。

如果您将std::initializer_list 换成int,则一切正常。

我已将此问题报告给 Microsoft。 (将在可用时添加链接)

【讨论】:

It's not the first time crazy sh!t like this has happened.

以上是关于为啥具有默认参数 std::initializer_list 的 ctor 不可用(VS2019)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 std::initializer_list 不是内置语言?

为啥 `std::initializer_list` 不提供下标运算符?

为啥在使用大括号初始值设定项列表时首选 std::initializer_list 构造函数?

std::initializer_list 作为函数参数

空大括号是调用默认构造函数还是调用 std::initializer_list 的构造函数?

为啥我的编译器无法计算出这种转换,它何时存在?