LINUX.ORG.RU

Подскажите контейнер для const обьектов

 ,


1

5

Все прекрасно знают (или сейчас узнают), что std::vector не умеет в const T. Хотя, вполне себе можно представить как такой контейнер будет себя вести:

  • под капотом std::aligned_alloc
  • добавляем через emplace_back(Args&&), который делает placement new
  • operator[] отдает через std::launder (C++17)

У меня есть метод, что подтягивает данные с базы. Хочу возвращать контейнер с const обьектами. Чтоб означить, что их не следует менять. Конечно ничего не мешает возвращать не-const

Есть ли что-нибудь на замену std::vector, чтоб самому не писать? Может boost?

std::vector не умеет в const T

Тому шо const объекты не assignable? Дам совет (возможно дебильный) - пробуй указатели хранить.

Meyer ★★★★★
()
Последнее исправление: Meyer (всего исправлений: 1)

Ну и вдогонку: у контейнеров transitive constness, так что по феншую, наверное, const std::vector<T>

anonymous
()
Ответ на: комментарий от anonymous

В static_assert в больлинстве реализаций:

/usr/local/include/c++/8.2.0/bits/stl_vector.h:351:21: error: static assertion failed: std::vector must have a non-const, non-volatile value_type
       static_assert(is_same<typename remove_cv<_Tp>::type, _Tp>::value,

Makhno
()

Может что-то типа

struct ImmutableT
{
    const T value;
    ImmutableT& operator=(const ImmutableT&) =delete;
}

и положить это в vector<ImmutableT>

GPFault ★★
()

std::deque, ссылки на массивы, объект типа cbegin() + cend() на вектор - нечто вроде std::span

anonymous
()
#include <vector>

template <typename T>
struct Wrapper
{
    Wrapper(T t) : val(t) {}
    
    const T val;
};

int main()
{
    std::vector<Wrapper<int>> v;
    v.emplace_back(42);
    // v[0].val = 1488;
}

А если так?

Только что заметил, что выше предложили уже что-то подобное.

zamazan4ik ★★
()
Последнее исправление: zamazan4ik (всего исправлений: 2)
Ответ на: комментарий от Meyer

Дам совет (возможно дебильный) - пробуй указатели хранить.

Да, но тогда обьекты сами надо где-то хранить. Что в принципе реализуемо: например другой вектор.

KennyMinigun ★★★★★
() автор топика
Ответ на: комментарий от next_time

std::array не поможет?

std::array не умеет в динамическую длинну.

KennyMinigun ★★★★★
() автор топика

const std::vector<T> обеспечивает неизменяемость хранимых объектов снаружи (без фокусов типа const_cast разумеется). Зачем что-то еще?

CatsCantFly
()
Ответ на: комментарий от vtVitus

Спасибо. Хотя осталось не особо понятно откуда это требование:

17.6.3.5 Allocator requirements

T any non-const object type

anonymous
()
Ответ на: комментарий от anonymous

Не пойму, зачем вектору понадобилось запрещать const T?

Оптимализация в основном. Но еще, например, невозможность делать insert() в начало и середину такого вектора.

KennyMinigun ★★★★★
() автор топика
Ответ на: комментарий от KennyMinigun

Такое ощущение, что вам нужна тривиальная собственная обертка вокруг обычного std::vector. Только вы из этой обертки будете выставлять наружу лишь const-методы и один-единственный emplace_back.

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

Хотя осталось не особо понятно откуда это требование

Из стандарта.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.