Reputation: 1603
I have a std::vector<std::string> tileSet_
as a member variable of a class. In the constructor of said class I call the function
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;
}
}
which at the very end attempts to push back a randomly picked string from a pair contained in the vector tileAmounts
into the memeber vector. For some reason, this raises the error
no matching member function call to 'push_back'
Why does this happen. I'm taking the vector to be pushed back from a std::pair
, but surely that shouldn't be causing any type mismatches? A std::string
in a std::pair
contained in a std::vector
is still a std::string
, no?
Upvotes: 1
Views: 272
Reputation: 264551
Took me a while to get it all building (with some guesses).
The problem is that the method is marked const
. Thus you are not allowed to call any mutating functions on members (ie you can not call none const member functions or none const member functions on any member variables).
void MapWindow::shuffleTiles() const
^^^^^
...
tileSet_.push_back(s); // Attempt to mutate the state of the object.
This is explained in greate detail in the error message generated by the compiler:
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);
If you go to the end of the line it says: "but method is not marked const"
Deciphering line:
note: candidate function not viable: 'this' argument has type
'const std::vector', but method is not marked const
void push_back(const_reference __x);note: candidate function not viable: 'this' argument has type
'const std::vector', but method is not marked const
void push_back(value_type&& __x);
Upvotes: 3
Reputation: 1603
I figured out the source of the problem: the vectortileSet_
didn't use to be a member variable, but I made it so out of necessity. I had, however, originally defined the function shuffleTiles
as a const
function, which of course makes it impossible for it to change the state of the class. Removing the const
from the definition fixed the issue.
The error messages in C++ can sure be mystical.
Upvotes: 1