Ответ 1
Цикл для цикла на основе диапазона может выполнять итерацию для любого выражения e
, тип класса которого имеет функции-члены e.begin()
и e.end()
, или функции, не являющиеся членами begin(e)
и end(e)
, можно найти через ADL. Следовательно, простой итеративный вид может быть следующим:
#include <cstddef>
template <typename T>
struct view
{
T* p;
std::size_t s;
constexpr T* begin() const { return p; }
constexpr T* end() const { return p + s; }
};
а затем вернул, удерживая указатель на массив, например, со статической продолжительностью хранения:
inline view<const int> conditional_range(bool a)
{
static int ra[] = { 1, 2 };
static int rb[] = { 3, 4, 5 };
if (a) return { ra, 2 };
else return { rb, 3 };
}
Это похоже на то, что c++20 предлагает с std::span
.
std::initilizer_list<T>
оборачивает локальный массив, автоматически созданный из заключенного в скобки инициализатора, и поэтому его нельзя использовать в качестве возвращаемого типа, поскольку в таком случае сохраненные в нем указатели становятся недействительными при выходе из функции.