Ссылка как параметр - PullRequest
0 голосов
/ 23 октября 2018

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

std::string pluralize(std::string const& word) {
if (uncountables.count(word) > 0) {
    return word;
}

for (auto const& r : rules) {
    if (r.matches(word)) {
        return r.pluralize(word);
    }
}

// The last rule is fully generic "append s" rule, so we cannot
// get here unless something is seriously wrong.
throw std::runtime_error("Word '" + word + "' did not match any rule");
}

std::vector<std::string> pluralize(std::vector<std::string> const& words) {

for (auto word : words) {
    word = pluralize(word);
    std::cout << word << " word from pluralize called with vec" << std::endl;
}
std::cout << words[0] << " 0 word from pluralize called with vec" << std::endl;
std::cout << words[1] << " 1 word from pluralize called with vec" << std::endl;
return words;
}

Когда вызывается метод множественного числасо строкой в ​​качестве параметра, она работает как ожидалось: изменяя значение переданного слова.При вызове с помощью vec он не меняет значения передаваемых строк.Вот мои тесты:

Код отлично работает для этих тестов:

SECTION("Respects capitalization") {
    REQUIRE(pluralize("Car") == "Cars");
    REQUIRE(pluralize("Mouse") == "Mice");
    REQUIRE(pluralize("German") == "Germans");
    }

Эти тесты не пройдены:

REQUIRE(
        pluralize({"Car", "Mouse", "German"}) == make_vec({"Cars", "Mice", "Germans"})
    );

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Вы не можете изменить words, так как это const.
Вы не замечаете этого, потому что не изменяете его - выводимый тип в for (auto word : words) равен std::string, а не std::string&.

Вы можете, например, скопировать ввод и изменить свою копию:

std::vector<std::string> pluralize(std::vector<std::string> const& words)
{
    std::vector<std::string> plurals = words;
    for (auto& word : plurals) {
        word = pluralize(word);
    }
    return plurals;
}

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

std::vector<std::string> pluralize(std::vector<std::string> const& words)
{
    std::vector<std::string> plurals;
    for (const auto& word : words) {
        plurals.push_back(pluralize(word));
    }
    return plurals;
}

или использовать std::transform:

std::vector<std::string> pluralize(std::vector<std::string> const& words)
{
    std::vector<std::string> plurals;
    std::transform(words.begin(), words.end(), std::back_inserter(plurals), pluralize);
    return plurals;
}

или другое решение ...

0 голосов
/ 23 октября 2018

Проблема здесь:

for (auto word : words) {
    word = pluralize(word);
}

Переменная word здесь представляет собой строку значение .Вы меняете это значение, но это не меняет слово в векторе.Попробуйте использовать ссылку:

for (auto& word : word) {
    word = pluralize(word);
}

auto не выводит ссылку.

Редактировать: Вы не можете изменить элемент в векторе, как у вас естьэто как ссылка на const.Один из способов исправить это - взять копию вектора.Самый простой способ сделать это - изменить сигнатуру функции для передачи по значению:

std::vector<std::string> pluralize(std::vector<std::string> words) {
    for (auto& word : words) {
        word = pluralize(word);
    }
    return words;
}
...