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

时间:2018-08-03 04:30:34

标签: c++ g++ clang++ initializer-list

下面的示例程序代码背后的思想是说明一个事实,即在给定一个元素的情况下,拥有与默认副本构造函数不相等的初始化列表构造函数可能导致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兼容的语法调用示例程序的初始化列表构造函数?

1 个答案:

答案 0 :(得分:3)

Clang实现了DR 1467(从T初始化T的行为就好像您没有使用花括号一样),但尚未实现DR 2137认为,仅对聚集体执行此操作。

您的代码应返回2。

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