C++ c++;11阵列初始化赢得';t调用复制构造函数

C++ c++;11阵列初始化赢得';t调用复制构造函数,c++,c++11,constructor,uniform-initialization,stdarray,C++,C++11,Constructor,Uniform Initialization,Stdarray,我正在创建一个小类,它使用一个按大小模板化的数组。这里有一些代码 .水电站 您在C++中遇到了一个缺陷:从单个元素初始化列表。C++11和C++14国际标准中规定的行为令人惊讶。我将参考下面的C++14 std::array的模板实例化是聚合[array.overview]/2。因此,当从带括号的init列表初始化std::array对象时,将不区分初始化器[dcl.init.list]/3.1的数量执行聚合初始化。由于某些构造(例如,来自一对迭代器)的要求,其他容器类不能聚合 聚合初始化(可能

我正在创建一个小类,它使用一个按大小模板化的数组。这里有一些代码

.水电站


您在C++中遇到了一个缺陷:从单个元素初始化列表。C++11和C++14国际标准中规定的行为令人惊讶。我将参考下面的C++14

std::array
的模板实例化是聚合[array.overview]/2。因此,当从带括号的init列表初始化
std::array
对象时,将不区分初始化器[dcl.init.list]/3.1的数量执行聚合初始化。由于某些构造(例如,来自一对迭代器)的要求,其他容器类不能聚合

聚合初始化(可能递归地)初始化初始化器中的数据成员。在您的情况下,它将尝试从初始值设定项
sequence
(类型相同)初始化
std::array
的第一个数据成员。对于
std::array
的所有实现,我知道
std::array
的第一个数据成员是一个C样式的数组。列表初始化将尝试从原始初始值设定项初始化该数组的第一个元素:
sequence

例如:

struct aggregate
{
    int m[2];
};

aggregate x = {0, 1};
assert(x.m[0] == 0 && x.m[1] == 1);

aggregate y{x}; // error: cannot convert `aggregate` to `int`
最后一行中的初始化将尝试从
x
初始化
y.m[0]


描述此问题和相关问题,即在没有初始值设定项时初始化列表。提议的决议为列表初始化引入了一个(又一个)特例,该特例在引用github最近的草案[dcl.init.list]/3.1中涵盖了这个问题

如果
T
是一个类类型,并且初始值设定项列表有一个元素 键入cv
U
,其中
U
T
或从
T
派生的类,对象是 从该元素初始化(通过复制初始化 复制列表初始化,或通过直接初始化 直接列表初始化)

最近草稿中的聚合初始化具有较低的“优先级”(3.3),也就是说,只有在不满足上述条件时才会执行



g++(5.0)和clang++(3.7.0)的最新版本甚至在C++11模式下也实现了建议的解决方案。

这是std::array的一个怪癖,也是C++14的一个缺陷。该容器必须是聚合容器,并且在C++14中使用单个元素进行列表初始化是有缺陷的。见@dyp好的,谢谢。这是否意味着我可以在C++17中看到修复?建议的解决方案确实出现在最近的草稿中,因此我希望它在下一个标准版本中得到修复。顺便说一句,这与
std::initializer\u list
无关。这是一个类模板,用于简化大括号init列表中的某些初始化。后者是
{..}
初始值设定项构造的语法名称。
template <size_t N>
KeyCombinationListener<N>::KeyCombinationListener(
    const array<sf::Keyboard::Key, N>& sequence, function<void (void)> fn
    ) : combo(sequence), progress{begin(combo)}, callback{fn}
{

}
Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
Target: x86_64-pc-linux-gnu
Thread model: posix
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9.2
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/4.9.2
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9
Candidate multilib: .;@m64
Selected multilib: .;@m64
struct aggregate
{
    int m[2];
};

aggregate x = {0, 1};
assert(x.m[0] == 0 && x.m[1] == 1);

aggregate y{x}; // error: cannot convert `aggregate` to `int`