5

構造体ごとに毎回再帰関数をグローバルに定義せずに、一般的な再帰関数を使用してツリーのような構造をトラバースしようとしました。

//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;
},
[&](...)
{
});

ここに大きな問題があります。

ここでのラムダ式は再帰的な形式で定義されているため、オブジェクトとそのコンテナーの型を指定する必要があります。

マクロはテンプレート関数のような型を推測できますか? または、他の方法でこれを達成する必要がありますか?

4

3 に答える 3