采用 std::initializer_list 的构造函数优于其他构造函数
Constructor taking std::initializer_list is preferred over other constructors
我使用带有标志 -std=c++17
的 GCC 11.1.0 编译下面的代码。它发生在 stdout 上打印 initializer_list
.
我用带有标志 -std=c++17
的 MSVC 编译了相同的代码,但它打印了“复制构造函数”。哪个编译器更符合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 };
}
对于这样的东西,编译器几乎从不“自由选择”。如果是这样,我们几乎无法编写任何可移植的 C++ 代码。
[over.match.list] does give priority to initializer_list
constructors. Constructor function overloading under the rules of list initialization gets invoked at step 3.6。步骤 3.1-3.5 不适用,因为您的类型不符合任何这些情况。步骤 3.1 特别有趣,因为它专门用于调用复制构造函数而不是做其他事情,但它也仅适用于聚合。你的类型不是。
由于您的类型可以隐式转换为 int
,并且您的类型采用 initializer_list<int>
,因此有一种有效的方法可以构建与中类型的构造函数相匹配的 initializer_list
题。因此,这是构造函数 [over.match.list] 将 select.
所以在这种情况下,VC++是错误的。正如is Clang,显然。
我使用带有标志 -std=c++17
的 GCC 11.1.0 编译下面的代码。它发生在 stdout 上打印 initializer_list
.
我用带有标志 -std=c++17
的 MSVC 编译了相同的代码,但它打印了“复制构造函数”。哪个编译器更符合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 };
}
对于这样的东西,编译器几乎从不“自由选择”。如果是这样,我们几乎无法编写任何可移植的 C++ 代码。
[over.match.list] does give priority to initializer_list
constructors. Constructor function overloading under the rules of list initialization gets invoked at step 3.6。步骤 3.1-3.5 不适用,因为您的类型不符合任何这些情况。步骤 3.1 特别有趣,因为它专门用于调用复制构造函数而不是做其他事情,但它也仅适用于聚合。你的类型不是。
由于您的类型可以隐式转换为 int
,并且您的类型采用 initializer_list<int>
,因此有一种有效的方法可以构建与中类型的构造函数相匹配的 initializer_list
题。因此,这是构造函数 [over.match.list] 将 select.
所以在这种情况下,VC++是错误的。正如is Clang,显然。