C++构造函数采用大小为1的std::initializer_list

C++ constructor taking an std::initializer_list of size one

本文关键字:std initializer list 构造函数 小为 C++      更新时间:2023-10-16

下面的示例程序代码背后的想法是为了说明这样一个事实,即当只给定一个元素时,拥有一个不等价于默认副本构造函数的初始值设定项列表构造函数可能会导致Clang意外的结果。

它还表明,Clang和GCC在复制构造函数和初始化器列表构造函数之间没有实现相同的优先级,这在实践中使得这种类型的初始化器列表构造器不可能用于可移植代码。

// Include directive.
#include <initializer_list>
// The struct used in this case.
struct Foo
{
// Member value.
int val;
// Default constructor.
Foo() : val(0) {}
// Initializer list constructor.
Foo(std::initializer_list<Foo>) : val(2) {}
};

// Main function.
int main()
{
// Default constructed Foo object.
Foo foo_zero;
// It is not clear to me which constructor
// should be called by the following statement.
Foo foo_test = { foo_zero };
// Return exit code.
// Clang 6.0.0 returns 0 (i.e. implicit copy constructor was called for 'foo_test').
// GCC 8.2 returns 2 (i.e. initializer list constructor was called for 'foo_test').
return foo_test.val;
}

我的问题如下:

  1. 我的示例程序的返回值应该是多少(Clang和GCC似乎不一致(?

  2. 有没有一种方法可以用Clang和GCC使用的语法来调用我的示例程序的初始值设定项列表构造函数?

Clang实现了DR 1467(大括号从T初始化T的行为就像您没有使用大括号一样(,但尚未实现DR 2137(仔细想想,只对聚合执行此操作(。

您的代码应该返回2。

一种可能的解决方法是Foo foo_test({ foo_zero });