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