我可以依赖 initializer_list::const_iterator 作为普通指针吗?
Can I rely on initializer_list::const_iterator being a plain pointer?
This question indicates that std::initializer_list<int>::const_iterator
type is just a plain int const*
pointer, but the wording of the standard as cited in this answer(对同一个问题)对我来说更像是建议而不是保证。
在我的代码中,问题发生如下:我有一个函数处理 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 ... }
是的,你可以依靠它,C++14 中的 18.9 给了我们里面 class initializer_list
的定义:
typedef const E* iterator;
typedef const E* const_iterator;
C++ 中的其他类型不同——例如 std::vector
,其中迭代器是实现定义的,有些实现使用原始指针作为迭代器,有些使用 class。
标准第18.9节给出<initializer_list>
header的概要如下:
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()
函数保证return一个const E*
,从18.9.2可以看出.
所以是的,你可以依靠它。
This question indicates that std::initializer_list<int>::const_iterator
type is just a plain int const*
pointer, but the wording of the standard as cited in this answer(对同一个问题)对我来说更像是建议而不是保证。
在我的代码中,问题发生如下:我有一个函数处理 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 ... }
是的,你可以依靠它,C++14 中的 18.9 给了我们里面 class initializer_list
的定义:
typedef const E* iterator;
typedef const E* const_iterator;
C++ 中的其他类型不同——例如 std::vector
,其中迭代器是实现定义的,有些实现使用原始指针作为迭代器,有些使用 class。
标准第18.9节给出<initializer_list>
header的概要如下:
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()
函数保证return一个const E*
,从18.9.2可以看出.
所以是的,你可以依靠它。