Привет, я пытаюсь изменить содержимое моего 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;
}

Когда метод pluralize вызывается со строкой в качестве параметра, он работает так, как ожидалось: изменяет значение переданного слова. При вызове с помощью 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"})
    );
1
Yevgen Ponomarenko 23 Окт 2018 в 12:00

2 ответа

Лучший ответ

Вы не можете изменить 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
molbdnilo 23 Окт 2018 в 09:43

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

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

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

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

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

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

std::vector<std::string> pluralize(std::vector<std::string> words) {
    for (auto& word : words) {
        word = pluralize(word);
    }
    return words;
}
0
Chris Drew 24 Окт 2018 в 19:57
52945088