I have a function that takes three structs and list of widgets. I want to link all of these widgets with particular field in struct and then process accordingly.
struct SomeStruct { QString first; QString second; QString third; ... };
void manipulateData(const QList<SomeObject*>& list, const SomeStruct& a, const SomeStruct& b, const SomeStruct& c)
{
}
What I could do, is just have boilerplate code in the form:
list[0]->setValue(a.first);
list[0]->setData(b.first + c.first);
list[1]->setValue(a.second);
list[1]->setData(b.second + c.second);
... (maybe more for each)
But I am trying to do it a bit better, so my initial idea is to create a list of structs with form that is comfortable to use:
void manipulateData(const QList<SomeObject*>& list, const SomeStruct& a, const SomeStruct& b, const SomeStruct& c)
{
struct TempStruct { SomeObject* obj; QString a; QString b; QString c; };
QList<TempStruct> tempList = {
{list[0], a.first, b.first, c.first},
{list[1], a.second, b.second, c.second},
...
}
for(const auto& item: tempList)
{
item.obj->setValue(item.a);
item.obj->setData(item.b + item.c);
}
}
This way this is easier to add new row to my list of structs.
The problem I still have, is it still doesn’t feel like the best idea, since I have to repeat words `a.first, b.first, c.first’. What would be enough, is to populate it with some kind of ‘way’ to retrieve ‘first’, ‘second’, ‘third’ in struct ‘SomeStruct’. So in the end, I would like my structure to look (and be populated) somehow like this:
void manipulateData(const QList<SomeObject*>& list, const SomeStruct& a, const SomeStruct& b, const SomeStruct& c)
{
struct TempStruct { SomeObject* obj; int getter}; //not sure about the type of getter
QList<TempStruct> tempList = {
{list[0], &a.first - &a}, //diff in memory place?
{list[1], &a.second - &a},
...
}
for(const auto& item: tempList)
{
item.obj->setValue(*(&a+item.getter));
item.obj->setData(*(&b+item.getter) + *(&c+item.getter));
}
}
I am not sure about types in my last example (consider it a pseudocode) – I have two questions:
- Is it safe to assume, that &c + &(b.second)-&b=&(c.second) ?
- Is there a better solution, maybe more clear?
I’ve included some explanation about question 1 (is my understanding is correct?)
6
I’ve found a solution, not sure if this is the best and I am still open for better answers or upgrading this answer. Instead of having getter
as a difference of addresses (as in last example), I used lambda functions.
void manipulateData(const QList<SomeObject*>& list, const SomeStruct& a, const SomeStruct& b, const SomeStruct& c)
{
struct TempStruct { SomeObject* obj; std::function<QString(SomeStruct)> fun}; //return type can be also variant type or just pointer to field (any type), would require to be cast later
QList<TempStruct> tempList = {
{list[0], [](const SomeStruct& s) { return s.first; }},
{list[1], [](const SomeStruct& s) { return s.second; }},
...
}
for(const auto& item: tempList)
{
item.obj->setValue(item.fun(a));
item.obj->setData(item.fun(b) + item.fun(c));
}
}
I would say you should probably rethink the design 🙁
ESBM74 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1