Я попытался пройти древовидные структуры с помощью универсальной рекурсивной функции, не определяя рекурсивную функцию в глобальном масштабе каждый раз для каждой структуры.
//structure #1
class CA
{
public:
std::string name;
std::vector<CA*> vecChild;
};
, и я создаю дерево с CA
auto root = new CA;
root->name = "root";
root->push_back(new CA);
auto& childA = root->back();
childA->name = "childA";
root->push_back(new CA);
auto& childB = root->back();
childB->name = "childB";
...
Я могу использовать этот макрос для обхода этой структуры, и это может работать с другими древовидными структурами.
#define Combinator(obj, combinatorObjToContainer, containerNameOfObj, invokingGetCount, combinatorContainerToIndexingItem, TAnyObject, TAnyContainer, argEnterFunc, argLeaveFunc)\
{\
std::function<void(TAnyObject, TAnyContainer)> RecursFunc = [&](auto& argObj, auto& argContainer)\
{\
argEnterFunc(argObj, argContainer);\
for(size_t idx=0; idx<argObj combinatorObjToContainer containerNameOfObj invokingGetCount; ++idx)\
{\
RecursFunc(argObj, argObj combinatorObjToContainer containerNameOfObj combinatorContainerToIndexingItem [idx]);\
}\
argLeaveFunc(argObj, argContainer);\
}\
}
Трудно читать, но работает нормально, я перехожу корень CA вот так
Combinator(root, ->, vecChild, .size(), , CA*, std::vector<CA*>&,
[&](auto& item, auto& vec)
{
std::cout << item.name << std::endl;
},
[&](...)
{
});
Работает с другой структурой, например:
struct MyData;
struct MyList
{
int count;
MyData* pItem;
};
struct MyData
{
char* name;
MyList* pLstChild;
};
Обход корня MyData
Combinator(root, ->, pLstChild, ->count, ->pItem, MyData*, MyList*,
[&](auto& pItem, auto& pLst)
{
std::cout << pItem->name << std::endl;
},
[&](...)
{
});
Здесь есть серьезная проблема.
Я должен указать тип объекта и его контейнер, потому что здесь лямбда-выражение определено в рекурсивной форме.
Может ли макрос выводить тип, такой как функция шаблона?или, может быть, я должен достичь этого по-другому?