c ++, указатели, ссылки, переход от одной функции к другой, std :: vector, std :: string - PullRequest
0 голосов
/ 18 августа 2011

У меня есть специфическая проблема с указателями и ссылками, с std :: vector и std :: string. Некоторые вопросы приведены в следующем фрагменте кода, некоторые ниже.

У меня есть в основном этот код

//first of all: is this function declaration good?
//or shoudl I already pass the std::vector in another way?
//I'm only reading from it
void func(const std::vector<std::string>& vec)
{
    //I need to call otherFunc(void*) with  a single element from vec:
    //otherFunc(void* arg);
    //with arg being a void* to vec[0]
}

Моя IDE говорит мне, что только &*vec[0] работает как параметр для otherFunc, но это не компилируется ...

Каков наилучший способ передачи параметров такого типа?

Ответы [ 3 ]

2 голосов
/ 18 августа 2011

Это хорошая декларация, если функция не предназначена для изменения вектора. Это более эффективно, чем передача по значению, поскольку позволяет избежать копирования вектора - дорогостоящая операция, требующая выделения памяти.

Однако для другой функции требуется неконстантный указатель. Как справиться с этим, зависит от того, может ли он изменить данные.

Если этого не произойдет (как вы подразумеваете, когда говорите: «Я только читаю с него»), то варианты:

  • Измените его на otherFunc(void const * arg), чтобы дать более сильную гарантию, что он не будет, или
  • Удалите квалификацию const с const_cast<void*> при вызове

Обратите внимание, что &*vec[0] не будет компилироваться; Вы хотите, чтобы vec[0].c_str() получил C-совместимый указатель на данные первой строки, предполагая, что это то, что вам нужно.

Если он может изменить вектор, вам придется сделать что-то еще, поскольку нет никакого законного способа изменить std::string через указатель на его данные. Вероятно, лучший вариант - использовать std::vector<char> вместо std::string, но это зависит от того, что именно делает функция.

1 голос
/ 18 августа 2011

Прежде всего, поскольку вы читаете только из вектора, передача его в качестве ссылки const является хорошей идеей и должна хорошо работать.

На ваш второй вопрос: трудно сказать, что otherFunc сделает с вашим объектом, поскольку он ожидает указатель void. Это стиль C, и его не следует использовать в C ++, для этого есть лучшие и безопасные способы.

1 голос
/ 18 августа 2011

Во-первых, &*vec[0] не имеет смысла; вы, вероятно, имеете в виду &vec[0] (то есть адрес первой строки в вашем векторе).

Но даже это не скомпилируется, потому что &vec[0] имеет тип const std::string *. Самое главное, это const. Вы могли бы сделать это:

otherFunc(const_cast<std::string *>(&vec[0]));

НО !!! Попытка использовать const std::string * в контексте void * звучит как очень плохая идея. Как это могло когда-нибудь сделать что-нибудь полезное?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...