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 (to the same question) sounds more like a suggestion than like a guarantee to me.
In my code, the problem occurs as follows: I have a function processing a sub-range of an initializer_list, and in a different situation I reuse the code from a convenience function passing a single element (as a single-element range):
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);
}
This construction relies on the fact that iterators are indeed pointers. It works at least with my clang++ 3.9 compiler. Can I rely on this to always work, i.e., is the pointer assumption portable? guaranteed to be portable? Or should I rather change the argument type of doStuff into a template parameter, to be on the safe side?
template <typename Iterator>
void doStuff(Iterator begin, Iterator end)
{ ... do stuff ... }
Yes, you can rely on it, 18.9 from C++14 gives us inside class initializer_list the definitions:
typedef const E* iterator;
typedef const E* const_iterator;
Other types in C++ are different -- for example std::vector, where the iterator is implementation defined, and some implementations use a raw pointer as an iterator, and some use a class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With