передать вектор с содержимым const - PullRequest
3 голосов
/ 07 июня 2019

У меня есть вектор, который выглядит следующим образом.

std::vector<std::pair<int,int> > v;

и я хочу передать это в функцию и сделать так, чтобы она была постоянной.

Сначала я попробовал

void fun(const std::vector<std::pair<int,int> > v)

но эта функция позволила мне получить строку

std::pair<int,int> p = v[i];

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

void fun(const std::vector<const std::pair<int,int> > v)

но это выдает ошибку из-за отсутствия конвертации.

Я уверен, что есть некоторые внутренние действия, которые я не понимаю, которые делают это незаконным, но хотелось бы немного понимания. Спасибо.

Ответы [ 2 ]

4 голосов
/ 07 июня 2019

Я думаю, что вы путаете семантику ссылок и значений здесь. Позволяет первой подписи функции, которую вы протестировали:

void fun(const std::vector<std::pair<int,int> > v)

Копирует аргумент функции в новый объект v, который дополнительно const -качественен. Такие подписи редко имеют смысл: либо вы хотите передать его как const ссылку (чтобы избежать копирования), либо вы хотите передать его не-const значением, потому что тело функции будет изменять аргумент, но должно работать с ним его единственная копия. Кроме того, этот фрагмент:

std::pair<int,int> p = v[i];

прекрасно компилируется с указанной выше сигнатурой функции, потому что копирует векторный элемент в позиции i в новый pair объект. Последний может быть видоизменен, но это вообще не влияет на вектор.

Теперь рассмотрим вторую сигнатуру функции:

void fun(const std::vector<const std::pair<int,int> > v)

То же, что и раньше, применимо и здесь, и, кроме того, std::vector<const T> бесполезен, см. эту ветку для объяснения.


Как это исправить? Если вы не хотите копировать аргумент, но функция не изменяет вектор, передайте его по ссылке const. Если функция изменяет вектор, и эти изменения должны быть видны на стороне вызова, передайте его как ссылку не const. Если функция изменяет вектор, но это должно происходить независимо от вектора стороны вызова, передавайте не-1030 * значение.

1 голос
/ 07 июня 2019
void fun(const std::vector<std::pair<int,int> > v)
{
   ////
   std::pair<int,int> p = v[i];
}

https://en.cppreference.com/w/cpp/container/vector/operator_at

Здесь не будет ошибки, поскольку std :: vector перегружен operator[] как для константных, так и для неконстантных экземпляров.В вашем случае он будет преобразован в постоянную версию и вернет const & базовому элементу i.
Рассмотрим следующий код:

void fun(const std::vector<std::pair<int,int> > v)
{
   ////
   std::pair<int,int> p = v[i]; //OK
   v[i] = std::pair<int,int>{10,20}; //Compile error, trying to modify const data!
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...