Выдвижение строки в приватный вектор-член - PullRequest
0 голосов
/ 30 октября 2019

У меня есть std::vector<std::string> tileSet_ в качестве переменной-члена класса. В конструкторе указанного класса я вызываю функцию

void MapWindow::shuffleTiles() const
{
  std::vector<std::pair<std::string, unsigned>> tileAmounts = {
    {"a", 2}, {"b", 4}, {"c", 1}, {"d", 4},
    {"e", 5}, {"f", 2}, {"g", 1}, {"h", 3},
    {"i", 2}, {"j", 3}, {"k", 3}, {"l", 3},
    {"m", 2}, {"n", 3}, {"o", 2}, {"p", 3},
    {"q", 1}, {"r", 3}, {"s", 2}, {"t", 1},
    {"u", 8}, {"v", 9}, {"w", 4}, {"x", 1}
  };

  int tileN = 0;
  for (std::vector<std::pair<std::string, int>>::size_type i = 0;
    i < tileAmounts.size();i++) {
    tileN += tileAmounts.at(i).second;
  }

  // only used once to initialise (seed) engine
  std::random_device rd;
  // random-number engine used (Mersenne-Twister in this case)
  std::mt19937 rng(rd());
  // guaranteed unbiased
  std::uniform_int_distribution<int> uni(0,tileAmounts.size() - 1);

  for (int i = 0; i < tileN; i++) {
    auto random_integer = uni(rng);
    //qDebug() << i << ":" << random_integer;
    std::cout << i
              << ":"
              << tileAmounts.at(random_integer).first
              << ":"
              << tileAmounts.at(random_integer).second
              << std::endl
              << std::endl;

    while (tileAmounts.at(random_integer).second < 1) {
      std::cout << "Reshuffling "
               << tileAmounts.at(random_integer).first
               << ":"
               << tileAmounts.at(random_integer).second
               << std::endl;
      random_integer = uni(rng);
    }

    std::string s = tileAmounts[random_integer].first;
    std::cout << s
              << std::endl;

    tileSet_.push_back(s);
    tileAmounts.at(random_integer).second -= 1;
  }

  for (std::vector<std::string>::size_type i = 0;
    i < tileSet_.size();i++) {
    std::cout << tileSet_.at(i)
              << std::endl;
  }
}

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

no matching member function call to 'push_back'

Почему это происходит. Я беру вектор, который будет отталкиваться от std::pair, но, конечно, это не должно вызывать каких-либо несоответствий типов? std::string в std::pair, содержащемся в std::vector, все еще является std::string, нет?

Ответы [ 2 ]

2 голосов
/ 30 октября 2019

Мне потребовалось время, чтобы все это строилось (с некоторыми догадками).

Проблема в том, что метод помечен const. Таким образом, вам не разрешается вызывать какие-либо мутирующие функции для членов (то есть вы не можете вызывать никакие константные функции-члены или никакие константные функции-члены для любых переменных-членов).

 void MapWindow::shuffleTiles() const
                                ^^^^^
 ...
     tileSet_.push_back(s);  // Attempt to mutate the state of the object.

Это подробно объясняется всообщение об ошибке, сгенерированное компилятором:

t2.cpp:61:14: error: no matching member function for call to 'push_back'
    tileSet_.push_back(s);
    ~~~~~~~~~^~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:712:36: note: candidate function not viable: 'this' argument has type
      'const std::vector<std::string>' (aka 'const vector<basic_string<char, char_traits<char>, allocator<char> > >'), but method is not marked const
    _LIBCPP_INLINE_VISIBILITY void push_back(const_reference __x);
                                   ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:715:36: note: candidate function not viable: 'this' argument has type
      'const std::vector<std::string>' (aka 'const vector<basic_string<char, char_traits<char>, allocator<char> > >'), but method is not marked const
    _LIBCPP_INLINE_VISIBILITY void push_back(value_type&& __x);

Если вы идете до конца строки, оно говорит: «, но метод не помечен const »

Расшифровка строки:

примечание: функция-кандидат недопустима: аргумент 'this' имеет тип
'const std :: vector', но метод не помечен const
void push_back (const_reference __x);

примечание: функция-кандидат недопустима: аргумент 'this' имеет тип
'const std :: vector', но метод не помечен const
void push_back (value_type && __x);

0 голосов
/ 30 октября 2019

Я выяснил источник проблемы: вектор tileSet_ не использовался в качестве переменной-члена, но я сделал это по необходимости. Однако я изначально определил функцию shuffleTiles как функцию const, что, конечно, делает невозможным изменение состояния класса. Удаление const из определения устранило проблему.

Сообщения об ошибках в C ++ могут быть мистическими.

...