Reputation: 125
I am being passed an array with values that I need to pass on to a few objects to store them. The array is two-dimensional of the form
{{int ID, int iNewValue}, ...}
I do not know which or how many values are updated but the ID is unique and doesn't change. I am told the ID <-> value pair once so I could just use a massive switch statement to check the ID and pass the value to the correct object and correct setter function. I thought I could make it more efficient and convenient and use a lookup-table where the index is the ID and the element is a pointer to the correct member function:
for (int i = 0; i < iNewValueLength; i++)
{
int ID = arrayNewValues[i][0];
int iNewValue = arrayNewValues[i][1];
(object.*lookup_table[ID])(iNewValue);
}
However, I am running into two issues:
I have multiple objects per class so I would need to be able to have individual entries in my lookup_table for different individual objects (even though they have the same functions). As an example, I have different humans and get updates to their height so I save the height setter function of each individual "human-object" and pass the updated height value to the correct object when I get an update. lookup_table[5]
might point to the height setter function of human-object number 2. I am having trouble understanding how to implement this, I've stumbled over this question. Is this what I want or is there another way?
I have multiple different classes so I can't put it all inside one lookup table (or can I?). Since I have no control over how the IDs are assigned which means I cannot they assume they are in order and do something like
if (ID < 10) (object1.*lookup_table_object1[ID])(iNewValue);
else if (ID < 20) (object2.*lookup_table_object2[ID])(iNewValue);
...
What should I do?
Thanks in advance for any help or pointers in the right direction!
Upvotes: 1
Views: 910
Reputation: 23497
Consider the following exemplary classes that have some member functions accepting int
arguments:
struct X {
void f1(int i) const { std::cout << "X::f1(" << i << ")\n"; }
void f2(int i) const { std::cout << "X::f2(" << i << ")\n"; }
};
struct Y {
void f1(int i) const { std::cout << "Y::f1(" << i << ")\n"; }
void f2(int i) const { std::cout << "Y::f2(" << i << ")\n"; }
};
Now, suppose you have some objects of these classes:
X x;
Y y;
To accomplish your goal, you can create a lookup table with value type std::function<void(int)>
:
std::map<int, std::function<void(int)>> m;
Then, you can populate such a lookup table with lambdas (or use std::bind
in the old way) that represent particular combinations of objects (possibly different objects of different classes) and their member functions:
m[1] = [&x](int i){ x.f1(i); };
m[2] = [&x](int i){ x.f2(i); };
m[3] = [&y](int i){ y.f1(i); };
m[4] = [&y](int i){ y.f2(i); };
Finally, to invoke these functions:
m[3](12);
m[2](-1);
Which outputs:
Y::f1(12)
X::f2(-1)
Live demo: https://wandbox.org/permlink/GGPaNJ15EIm9g5gy.
Just beware of possible dangling references in lambdas. The referenced objects generally need to exist as long as the entries in the lookup table are linked to them.
Upvotes: 1