У меня есть класс с std :: vector<ИНТ> member и функция-член, возвращающая константную ссылку на этот вектор.
class demo {
public:
//...
const std::vector<int> & test() const {
return iv;
}
private:
std::vector<int> iv;
};
Я планирую изменить тип члена на другой массив, такой как тип контейнера, с достаточной функциональностью и меньшим объемом памяти (например, std :: экспериментальный :: dynarray, std :: unique_ptr<ИНТ []>). Поэтому я подумал, что было бы неплохо не возвращать реальный контейнер как константную ссылку, а возвращать представление элементов в виде gsl :: span<const int>,
class demo {
public:
//...
gsl::span<const int> test() const {
return iv;
}
private:
std::vector<int> iv;
};
Но это нарушает код, который работал с константным вектором<ИНТ>& потому что два экземпляра span одного и того же неизмененного вектора не могут быть использованы для итерации по элементам:
demo d;
std::cout << (d.test().begin() == d.test().begin()) << "\n";
std::cout << (d.test().end() == d.test().end()) << "\n";
for( auto it = d.test().begin(), end = d.test().end(); it != end; ++it )
std::cout << *it << "\n";
Это печатает 0 0 и затем терпит крах, потому что проверить это! = End никогда не терпит неудачу.
Конечно, диапазон, основанный на цикле, работает, но этот цикл действителен и поэтому должен также работать как положено.
Я ожидал, что все диапазоны из одного и того же диапазона одного и того же контейнера равны, так что итераторы любого из этих диапазонов сопоставимы (контейнер, конечно, не изменен). Конечно, есть веская причина, почему это не так.
Поэтому мой вопрос заключается в том, каков наилучший способ вернуть такое представление элементам массива, таким как контейнер, тип которых не должен быть виден вызывающей стороне.
Ты используешь iterator
временный, так что ваш iterator
стать инвалидом сразу после воздействия.
Вы можете использовать следующее:
auto&& view = d.test();
for (auto it = view.begin(), end = view.end(); it != end; ++it) {
std::cout << *it << "\n";
}
Так что ответ НЕТ, потому что это нарушает код, который был действителен раньше.