#include <iostream>
#include <fstream>
#include <functional>
#include <vector>
class Monkey
{
public:
int itemsProcessed{0};
std::vector<int> heldItems;
std::function<int(int)> operationFunction;
std::function<int(int)> testFunction;
Monkey(std::vector<int> sI, std::function<int(int)> oF, std::function<int(int)> tF)
{
heldItems = sI;
operationFunction = oF;
testFunction = tF;
}
void addItem(int item)
{
heldItems.push_back(item);
}
std::vector<std::pair<int, int>> processItems()
{
std::vector<std::pair<int, int>> redistributedItems;
for (auto i : heldItems)
{
int adjusted = operationFunction(i);
// Divide by 3 after monkey doesn't break it. Floor is applied by default for int division
adjusted /= 3;
int toMonkey = testFunction(adjusted);
redistributedItems.emplace_back(toMonkey, adjusted);
}
return redistributedItems;
}
};
int main(int argc, char *argv[])
{
std::vector<Monkey> monkeyList;
monkeyList.emplace_back(
{79, 98}, [](int a) -> int
{ return a * 19; },
[](int a) -> int
{ return a % 23 ? 2 : 3; });
return EXIT_SUCCESS;
}
In case you're wondering, this is a solution I'm working on for advent of code not any sort of programming assignment.
The issue I'm facing is that I'd like to create a vector of Monkey objects in my main method. It seems to me that I should be able to pass the arguments to the Monkey class constructor (vector, lambda, lambda) to the emplace_back function of the vector class. Whenever I try the above code I get the following error:
error: no matching function for call to 'std::vector<Monkey>::emplace_back(<brace-enclosed initializer list>, main(int, char**)::<lambda(int)>, main(int, char**)::<lambda(int)>)'
41 | monkeyList.emplace_back(
| ~~~~~~~~~~~~~~~~~~~~~~~^
42 | {79, 98}, [](int a) -> int
| ~~~~~~~~~~~~~~~~~~~~~~~~~~
43 | { return a * 19; },
| ~~~~~~~~~~~~~~~~~~~
44 | [](int a) -> int
| ~~~~~~~~~~~~~~~~
45 | { return a % 23 ? 2 : 3; });
If I wrap the arguments to emplace_back in braces to use brace initialization, I get the following error:
error: no matching function for call to 'std::vector<Monkey>::emplace_back(<brace-enclosed initializer list>)'
42 | monkeyList.emplace_back({{79, 98}, [](int a)
| ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
43 | { return a * 19; },
| ~~~~~~~~~~~~~~~~~~~
44 | [](int a)
| ~~~~~~~~~
45 | { return a % 23 ? 2 : 3; }});
What gives? I'd like monkeyList[0] to be an object with heldItems = vector of two ints, 79 and 98, an operationFunction of a lambada that takes an int and returns 19 * that int, and a lambda that returns 2 if the modulo of an int is 23 or 3 otherwise. Relatively new to C so any help is appreciated. Thanks.
CodePudding user response:
The problem is that the emplace_back
doesn't know the type of {79, 98}
when you're passing it. So you have to specify that it's a std::vector<int>
.
monkeyList.emplace_back(
std::vector<int>{79, 98}, [](int a) -> int
{ return a * 19; },
[](int a) -> int
{ return a % 23 ? 2 : 3; });
The reason is because emplace_back is using template parameters, and {79, 98}
could be anything, so the compiler doesn't know what it is and it's not allowed to guess.