为什么不起作用? (引用的初始化)

时间:2019-01-12 00:16:18

标签: c++ reference list-initialization

#include <array>

int main()
{
    struct A
    {
        unsigned char l;
        std::array<char, 12> c;
    };

    const A a = {1, "t"}; // OK
    const A& ar = {1, "t"}; // error: invalid initialization of reference of type 'const main()::A&' from expression of type '<brace-enclosed initializer list>'
}

(gcc 8.2,-std = c ++ 17)

This question谈论的是GCC错误,但该错误已久(7年前)。

请注意,我不在乎生命周期的延长,我实际上是将临时变量直接传递给函数使用而不是存储,但是我尝试使示例更简洁。


编辑:

  • 我不能使例子更小。特别是,它与array<char>有关。
  • 在“ t”周围添加更多花括号,但仍然失败。
  • 有效的方法是将字符串文字分解为字符:

    const A& ar = {1, {'a', 'b'}}; // works
    

1 个答案:

答案 0 :(得分:3)

首先要注意的是,初始化程序{1, "t"}使用
brace elision 来初始化子聚合A.c,这意味着文字"t"是用于直接初始化std::array所保存的内部数组。在这种情况下,该数组看起来像char data[12]

这可以简化为我们正在使用包含包含用于初始化成员数组的元素的括号列表初始化对const A的引用

这将等效于:

struct S {
    char const data[2];
};
S const& s = {"t"}; // fail for gcc

海湾合作委员会已为此设立了bug report

您已经在评论部分中提供了一种解决方法。只需将引用初始化为:

const A& ar = A{1, "t"}