Как передать ссылку на массив строк в качестве параметра функции во время выполнения, когда размер массива неизвестен в C ++? - PullRequest
0 голосов
/ 03 июля 2018

Следующий фрагмент кода работает нормально. Проблема в том, что он мне нужен, когда размер массива неизвестен. В приведенном ниже примере я жестко закодировал значения в 2. В реальном мире я не знаю размер. Есть ли способ изменить код, чтобы он работал, даже если размер массива неизвестен.

void namesArray(std::string (&numList)[2], std::string name)
{
    //This is just place holder code. Please ignore the logic. 
    numList[ 0 ] = "Peter" + name;
    numList[ 1 ] = "Bruce" + name;
}

int main()
{
    std::string nameList[2];
    namesArray( nameList, "Parker");
    std::cout << nameList[0]<< std::endl;
    std::cout << nameList[1] << std::endl;
    return 0;
}

Я НЕ МОГУ использовать любой другой тип данных (например, Векторы), кроме массивов из-за внешних ограничений.

Редактировать: Когда я говорю, что размер неизвестен, я имею в виду, что размер массива неизвестен до времени выполнения. Кроме того, то, что я представляю, это чрезмерное упрощение моего реального кода. Функция принимает только массивы.

ОБНОВЛЕНИЕ: Спасибо всем за предложенные решения. Похоже, код, который я уже написал, работал в моем решении. Я знаю, что странно использовать массивы, когда векторы предлагают больше гибкости. Однако при работе с унаследованным кодом у вас иногда нет выбора. СПАСИБО МНОГО ЗА ВСЕ ОТВЕТЫ ВСЕМ, КТО ОТВЕТИЛ. ЭТО ОЧЕНЬ ИНФОРМАЦИОННО.

Ответы [ 3 ]

0 голосов
/ 03 июля 2018

Самое простое решение - передать размер в массив:

void namesArray(std::string *numList, std::size_t numCount, std::string name)

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

Вот в чем дело: вы всегда знаете размер массива. Буквально невозможно написать код, который создает массив неизвестного размера. Вы можете (не) преднамеренно забыть размер массива, но в какой-то момент он должен знать , потому что иначе вы буквально не можете создать массив. Вы можете знать это только во время выполнения, потому что, скажем, оно определяется пользовательским вводом, но это просто означает, что оно находится в переменной, и вы все еще знаете это , у вас просто нет предопределенного значения во время компиляции .

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

0 голосов
/ 03 июля 2018

Вам представлено несколько решений. Я хотел бы представить другую, абстракцию, которая включает в себя несколько решений. Возьмите gsl::span (или std::span, если вы из будущего).

Пролет - это обобщенный взгляд на смежную последовательность элементов. И мощная абстракция.

Вы хотите передать массив статического размера? span может быть создан из одного через конструктор шаблона.
Вы хотите передать указатель и размер? span Тебя там тоже прикрыли.
Контейнер типа std::vector или std::array? Нет проблем.

Используйте span, если все, что вас волнует, это свойство последовательности, а не то, какой является сама последовательность.

0 голосов
/ 03 июля 2018

Если я хорошо понял ваш вопрос, вы можете использовать шаблонный механизм для вычитания размера массива:

#include <iostream>
#include <string>

template <size_t N>
void namesArray(std::string (&numList)[N], std::string name) {
    //This is just place holder code. Please ignore the logic.
    numList[ 0 ] = "Peter" + name;
    numList[ 1 ] = "Bruce" + name;
}

int main() {
    std::string nameList[5];
    namesArray( nameList, "Parker");
    std::cout << nameList[0]<< std::endl;
    std::cout << nameList[1] << std::endl;
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...