Указатель на вектор векторов в функции выдает ошибку «выражение должно иметь тип указателя»

#c #function #pointers #vector #stdvector

#c #функция #указатели #вектор #stdvector

Вопрос:

Код Visual Studio выдает ошибку «выражение должно иметь тип указателя» для строки int size = graph->at(node)->size(); . Я знаю, что мог бы использовать ссылки, но я хочу знать, как это сделать с помощью указателя.

 #include <vector>
using namespace std;
void getPathEdges(vector<vector<int>>* graph, int sink, int count, int node, vector<int>* path) {
    if (node == sink) {
        path->push_back(count);
    }
    else {
        count  ;
        int size = graph->at(node)->size();
        for (int i=0; i<size; i  ) {
            getPathEdges(graph, sink, count, i, path);
        }
    }
}
  

Комментарии:

1. Вы уже упоминали об этом в вопросе, но я просто хочу повторить ваше подтверждение ссылок. О необработанных указателях полезно знать, но как только вы начнете писать что-либо любого масштаба, вам захочется думать в терминах интеллектуальных указателей и ссылок, переходя только к необработанным указателям для взаимодействия со старыми библиотеками или когда у вас нет другого выбора.

Ответ №1:

Вы захотите

 graph->at(node).size();
  

Первый доступ — это a -> , потому что у вас есть vector<vector<int>>* (указатель). graph->at(node) возвращает a vector<int> (не указатель), поэтому доступ к нему осуществляется просто через . , не -> .

Ответ №2:

Вам нужно подумать о том, на что на самом деле указывает ваш указатель. Если мы уберем * из vector<vector<int>>* graph объявления, то у нас останется это: вектор векторов.

Итак, когда вы разыменовали указатель один раз graph->at() ), у вас остается только вектор (не указатель на вектор).). ( -> Разыменование указателя и at() вызов возвращают соответствующий внутренний вектор.)

Итак, просто замените второй -> в этой строке простым . оператором:

 #include <vector>
using namespace std;
void getPathEdges(vector<vector<int>>* graph, int sink, int count, int node, vector<int>* path)
{
    if (node == sink) {
        path->push_back(count);
    }
    else {
        count  ;
        int size = graph->at(node).size(); // Only dereference ONCE!
        for (int i = 0; i < size; i  ) {
            getPathEdges(graph, sink, count, i, path);
        }
    }
}
  

Ответ №3:

Проблема заключалась в том, что graph->at(node) указатель не возвращался, поэтому использование ->size() на нем было недопустимым. Изменить int size = graph->at(node)->size(); на int size = graph->at(node).size(); .