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

Ank*_*Dev 5 c++ g++ initializer-list clang++

下面的示例程序代码背后的想法是说明如果初始化程序列表构造函数在给定恰好一个元素时不等同于默认复制构造函数,则可能导致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;
}
Run Code Online (Sandbox Code Playgroud)

我的问题如下:

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

  2. 有没有办法让我的示例程序的初始化列表构造函数使用与Clang和GCC一起使用的语法调用?

T.C*_*.C. 3

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

您的代码应该返回 2。

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