采用STD::IMALIZIZER列表优于其他构造函数的C++构造函数

tyky79it  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(292)

我在下面用GCC11.1.0编译了这段代码,其中带有一个标志 -std=c++17 . 在标准输出上打印 initializer_list .
我用带有标志的msvc编译了相同的代码 -std=c++17 但它打印了“复制构造函数”。哪个编译器更符合cpp标准?编译器可以自由选择一个构造函数吗?


# include <iostream>

using namespace std;

struct S
{
    S(int) { }
    S(initializer_list<int>) { cout << "initializer_list"; }
    S(const S&) { cout << "copy constructor"; }

    operator int() const { return 1; };
};

int main()
{
    S s1(20);
    S s2{ s1 };
}
apeeds0o

apeeds0o1#

对于这样的东西,编译器几乎从不“自由选择”。如果是这样,我们就不能编写任何可移植的C代码。
[over.match.list]确实优先考虑 initializer_list 构造器。在步骤3.6中调用列表初始化规则下的构造函数重载。步骤3.1-3.5不适用,因为您的类型不符合上述任何情况。步骤3.1特别有趣,因为它专门用于调用复制构造函数,而不是执行其他操作,但它也仅适用于聚合。你不是那种类型的。
因为您的类型可以隐式转换为 int ,而且你的类型 initializer_list<int> ,有一种有效的方法可以构建 initializer_list 与所讨论类型的构造函数匹配的。因此,这是[over.match.list]将选择的构造函数。
所以在这种情况下,vc
是错误的。显然,叮当声也是如此。

相关问题