Приведение вектора <T>к вектору <const T> - PullRequest
29 голосов
/ 19 мая 2010

У меня есть переменная-член типа vector<T> (где T - это пользовательский класс, но также может быть и int.) У меня есть функция, из которой я хочу вернуть указатель на этот вектор, но я не хочу, чтобы вызывающая сторона могла изменять вектор или его элементы. Поэтому я хочу, чтобы тип возвращаемого значения был const vector<const T>*

Ни один из приведенных мною методов не сработал. Компилятор продолжает жаловаться, что T не совместим с const T.

Вот некоторый код, который демонстрирует суть того, что я пытаюсь сделать;

vector<int> a;
const vector<const int>* b = (const vector<const int>* ) (&a);

Этот код не компилируется для меня.

Заранее спасибо!

Ответы [ 5 ]

30 голосов
/ 19 мая 2010

Если у вас есть const vector<int>, вы не можете изменять контейнер, а также не можете изменять какие-либо элементы в контейнере. Вам не нужно const vector<const int> для достижения этой семантики.

15 голосов
/ 19 мая 2010

В дополнение к ответу Джеймса о том, как это сделать, следует отметить, что const int не является допустимым типом для помещения в любой стандартный контейнер, так как он не может быть назначен.

14 голосов
/ 20 мая 2010

О том, почему 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 приведет к разрыву система типов.

2 голосов
/ 19 мая 2010

вы можете форсировать конвертацию так:

b = reinterpret_cast<const std::vector<const int>*>(&a);

но я не думаю, что вы должны это делать, поскольку это не гарантирует работу, только для компиляции

1 голос
/ 20 мая 2010

Компилятор решает заблокировать это. Тем не менее, мы знаем, что это безопасно, поэтому, возможно, мы можем обмануть это:

const vector<const int>* b = (const vector<const int>* )(void *)(&a);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...