Ответ 1
Если у вас есть const vector<int>
, вы не можете модифицировать контейнер и не можете изменять какой-либо элемент в контейнере. Для достижения этой семантики вам не нужен const vector<const int>
.
У меня есть переменная-член типа vector<T>
(где T - это пользовательский класс, но он также может быть int.)
У меня есть функция, из которой я хочу вернуть указатель на этот вектор, но я не хочу, чтобы вызывающий мог изменить вектор или его элементы. Поэтому я хочу, чтобы возвращаемый тип был const vector<const T>*
Ни один из методов литья, которые я пробовал, работал. Компилятор продолжает жаловаться, что T несовместим с const T.
Вот какой код, который демонстрирует суть того, что я пытаюсь сделать,
vector<int> a;
const vector<const int>* b = (const vector<const int>* ) (&a);
Этот код не компилируется для меня.
Спасибо заранее!
Если у вас есть const vector<int>
, вы не можете модифицировать контейнер и не можете изменять какой-либо элемент в контейнере. Для достижения этой семантики вам не нужен const vector<const int>
.
В дополнение к ответу Джеймса о том, как это сделать, вы должны заметить, что const int
не является допустимым типом, который помещается в любой стандартный контейнер, поскольку он не может быть назначен.
В чем причина vector<T>
не может быть правильно преобразована в vector<const T>
, даже если T
можно преобразовать в const T
Это обычная повторяющаяся проблема при программировании, независимо от того, связана ли она с константой или наследованием (контейнер производного объекта не может быть преобразован в контейнер базовых объектов, даже если сами содержащиеся элементы). Проблема состоит в том, что элемент по элементу каждый из них может быть преобразован, но сам контейнер не может не нарушать систему типов.
Если вам разрешено делать vector< const T > &vr = my_vector_of_T
, вам будет разрешено добавлять элементы через vr
, и эти элементы будут по определению постоянными. Но в то же время те же самые элементы будут сглажены в my_vector_of_T
как неконстантные элементы и могут быть изменены через этот интерфейс, нарушая константу в системе типов.
В частном случае преобразования vector<int>
в vector<const int>
вероятность того, что вы не заметите действительно странные эффекты - помимо добавления элемента к vector<const int>
и видя, как изменяется постоянный элемент во времени, но помните, что для двух связанных типов T1
и T2
, для которых существует отношение, в большинстве случаев попытка применить одно и то же отношение к контейнерам T1
и T2
приведет к поломке системы типов.
вы можете принудительно выполнить преобразование следующим образом:
b = reinterpret_cast<const std::vector<const int>*>(&a);
но я не думаю, что вы должны это сделать, так как это не гарантируется, только для компиляции
Компилятор решает заблокировать это. Однако мы знаем, что это безопасно, поэтому, возможно, мы сможем обмануть его:
const vector<const int>* b = (const vector<const int>* )(void *)(&a);