嵌套的std :: initializer_lists的数据元素是否保证是连续的?

时间:2014-01-04 04:11:23

标签: c++ c++11 initializer-list

可以通过嵌套大括号括起来的列表来创建多维初始值设定项,如{{1,2,3}, {4,5,6}}中所示。接受此功能的函数可以使用嵌套的std::initializer_list s。

编写

数据元素是否保证是连续的?

以下是一个例子:

void f(std::initializer_list<std::initializer_list<int>> a)
{
  for(auto const & p: a)
    for(auto const & q: p)
      std::cout << &q << std::endl;
}

int main()
{
  f({{1,2,3}, {4,5,6}});
  return 0;
}

以上代码在我的机器上输出连续的地址。

0x400c60
0x400c64
0x400c68
0x400c6c
0x400c70
0x400c74

有保证吗?

更新

答案必须是否定。

void g(std::initializer_list<int> a, std::initializer_list<int> b)
{
  f({b,a});
}

int main()
{
  g({1,2,3}, {4,5,6});
  return 0;
}

输出结果为:

0x400cdc
0x400ce0
0x400ce4
0x400cd0
0x400cd4
0x400cd8

2 个答案:

答案 0 :(得分:7)

C ++11§[support.initlist] 18.9 / 1指定std::initializer_list<T> iterator必须为T*,因此保证单个{{1}中的顺序元素是连续的。

对于嵌套列表,例如initializer_list,不要求所有元素都是连续的。顶级列表的std::initializer_list<std::initializer_list<int>>必须返回指向begin()的连续数组的指针,并且每个列表'std::initializer_list<int>必须返回指向begin()的连续数组的指针。这些第二层int数组可以分散在整个内存中,或者按照您观察到的完全顺序存储。这两种方式都是合规的。

答案 1 :(得分:2)

来自here (std::initializer_list): -

  

初始化列表可以实现为一对指针或指针   和长度。

可能的实现(从Mingw 4.8.1 initializer_list标题中获取和编辑):

  template<class T>
    class initializer_list
    {
    public:
      typedef T         value_type;
      typedef const T&  reference;
      typedef const T&  const_reference;
      typedef size_t        size_type;
      typedef const T*  iterator;
      typedef const T*  const_iterator;

    private:
      iterator          arr;
      size_type         arr_len;

      // The compiler can call a private constructor.
      constexpr initializer_list(const_iterator it, size_type len)
      : arr(it), arr_len(len) { }

    public:
      constexpr initializer_list() noexcept
      : arr(0), arr_len(0) { }

      // Number of elements.
      constexpr size_type
      size() const noexcept { return arr_len; }

      // First element.
      constexpr const_iterator
      begin() const noexcept { return arr; }

      // One past the last element.
      constexpr const_iterator
      end() const noexcept { return begin() + size(); }
    };

迭代器不是魔术,它只是用指针来玩。所以答案是肯定的,保证。

在您的第二个示例中,它确实显示了连续的内存位置,您只需翻转ab