我可以依靠 initializer_list::const_iterator 是一个普通的指针吗?

Can I rely on initializer_list::const_iterator being a plain pointer?

本文关键字:一个 指针 list initializer 依靠 const iterator 我可以      更新时间:2023-10-16

这个问题表明std::initializer_list<int>::const_iterator类型只是一个普通的int const*指针,但这个答案(对同一个问题(中引用的标准措辞听起来更像是一个建议,而不是对我的保证。

在我的代码中,问题发生如下:我有一个处理initializer_list子范围的函数,并且在不同的情况下,我重用了传递单个元素(作为单元素范围(的便利函数的代码:

void doStuff(int const* begin, int const* end)
{ ... do stuff ... }
  // main use; in the real code, 'init' is a parameter of a function
  std::initializer_list<int> init({1, 2, 3, 4, 5});
  doStuff(init.begin() + 1, init.end());
  // alternative use of doStuff, relies on the pointer assumption
  int x = 6;
  doStuff(&x, (&x) + 1);
}

这种构造依赖于迭代器确实是指针的事实。它至少适用于我的 clang++ 3.9 编译器。我可以依靠它来始终工作,即指针假设是可移植的吗?保证便携吗?还是为了安全起见,我应该将doStuff的参数类型更改为模板参数?

template <typename Iterator>
void doStuff(Iterator begin, Iterator end)
{ ... do stuff ... }

是的,你可以依靠它,18.9 来自 C++14 为我们提供了class initializer_list定义:

typedef const E* iterator; typedef const E* const_iterator;

C++中的其他类型是不同的 - 例如std::vector,其中迭代器是实现定义的,一些实现使用原始指针作为迭代器,而一些实现使用类。

标准的第 18.9 节给出了<initializer_list>标头的概要,如下所示:

namespace std {
  template<class E> class initializer_list {
  public:
    typedef E value_type;
    typedef const E& reference;
    typedef const E& const_reference;
    typedef size_t size_type;
    typedef const E* iterator;
    typedef const E* const_iterator;
    constexpr initializer_list() noexcept;
    constexpr size_t size() const noexcept; // number of elements
    constexpr const E* begin() const noexcept; // first element
    constexpr const E* end() const noexcept; // one past the last element
  };
  // 18.9.3 initializer list range access
  template<class E> constexpr const E* begin(initializer_list<E> il) noexcept;
  template<class E> constexpr const E* end(initializer_list<E> il) noexcept;
}

此外,initializer_list上的begin()end()函数保证返回const E*,正如我们从 18.9.2 中看到的。

所以是的,你可以依靠它。