Как различить пару и вложенный map?

Пытаюсь пройтись рекурсивно по map и не могу понять как определить вложенный map, предполагаю что возможно как-то через касты указателей и последующее сравнение?

#include <iostream>
#include <string>
#include <map>

using namespace std;

bool isDictionary(void* ptr) {};

void flattenDictionaryHelper(string initialKey, map<string, void*> dict, map<string, string>& ans)
{
    for (auto& kvpair : dict)
    {
        auto value = dict[kvpair.first];

        if (!isDictionary(value)) // ??
        {
            if (initialKey == "")
                ans.insert_or_assign(kvpair.first, to_string(*(int*)&kvpair.second));
            else
                ans.insert_or_assign(initialKey + "." + kvpair.first, to_string(*(int*)&kvpair.second));
        }
        else
        {
            if (initialKey == "")
                flattenDictionaryHelper(kvpair.first, *(map<string, void*>*) & value, ans);
            else
                flattenDictionaryHelper(initialKey + "." + kvpair.first, *(map<string, void*>*) & value, ans);
        }
    }
}

map<string, string> flattenDictionary(const map<string, void*>& dict)
{
    map<string, string> ans;
    flattenDictionaryHelper("",dict,ans);
    return ans;
}

Ввод

int main() 
{
    map<string, void*> insidedict3{
        {"" , (void*)1}
    };
    map<string, void*> insidedict2{
        {"d",(void*)3},
        {"e",(void*)&insidedict3}
    };

    map<string, void*> insidedict{ 
        {"a", (void*)2},
        {"b", (void*)3 },
        {"c", (void*)&insidedict2}};
/*
input:  dict = {
            "Key1" : "1",
            "Key2" : {
                "a" : "2",
                "b" : "3",
                "c" : {
                    "d" : "3",
                    "e" : {
                        "" : "1"
                    }
                }
            }
        }
*/
    map<string, void*> dict{ {"Key1",(void*)1},{"Key2",(void*)&insidedict}};

    for (auto& in : flattenDictionary(dict))
        std::cout << in.first << " : " << in.second << std::endl;
    return 0;
}

Ответы (1 шт):

Автор решения: cpp-userium

Переделал с помощью темплейтов и ооп.

Осталось 2 проблемы:

  1. работает нормально только с одним типом данных(см. вывод)
  2. плохо читается
#include <iostream>
#include <string>
#include <map>

using namespace std;

template<class T>
struct Dict
{
public:
    char* type;
    void* ptr;
    T* realval;
};

class NestedDict : public Dict<map<string, void*>>
{
public:
    NestedDict(map<string, void*>* mapptr) : realval(mapptr) { Dict<map<string, void*>>::type = new char('n');};
    void* ptr = (void*)realval;
    map<string, void*>* realval{};
};

template<class T>
class Value: public Dict<T> // примитивный тип
{
public:
    Value(T* val) { Dict<T>::type = new char('k'); Dict<T>::realval = val; };
    void* ptr = (void*)Dict<T>::realval;
};

template<class T>
bool isDictionary(Dict<T>* ptr) {
    char t = *ptr->type;
    if (t == 'n')
        return true;
    else
        return false; 
};

template<class T>
void flattenDictionaryHelper(string initialKey, map<string, void*> dict, map<string, string>& ans)
{
    for (auto& kvpair : dict)
    {
        auto value = dict[kvpair.first];

        if (!isDictionary((Dict<T>*)value)) // примитивный тип
        {
            string insert_string; 
            Value<T>* val = (Value<T>*)value;
            T* right_val = (T*)val->realval;

            if (initialKey == "")
            {
                ans.insert_or_assign(kvpair.first, to_string(*right_val));
            }
            else
                ans.insert_or_assign(initialKey + "." + kvpair.first, to_string(*right_val));
        }
        else // map
        {
            if (initialKey == "")
                flattenDictionaryHelper<T>(kvpair.first, *(((NestedDict*)value)->realval), ans);
            else
                flattenDictionaryHelper<T>(initialKey + "." + kvpair.first, *(((NestedDict*)value)->realval), ans);
        }
    }
}
map<string, string> flattenDictionary(const map<string, void*>& dict)
{
    map<string, string> ans;
    flattenDictionaryHelper<int>("",dict,ans); 
    return ans;
}
int main()
{
    NestedDict insidedict3{
        new map<string, void*>{
            { "", (void*)new Value<int>(new int(1))}
        }
    };

    NestedDict insidedict2{
    new map<string, void*>{
        {"d",(void*) new Value<int>(new int(3))},
        {"e",(void*)&insidedict3}
    }
    };
    NestedDict insidedict1{
    new map<string, void*>{
        {"a", (void*) new Value<int>(new int(2))},
        {"b", (void*) new Value<int>(new int(3))},
        {"c", (void*)&insidedict2}
    }
    };

    map<string, void*> dict{ {"Key1",(void*) new Value<float>(new float(1.f))},{"Key2",(void*)&insidedict1}};

    for (auto& in : flattenDictionary(dict))
        std::cout << in.first << " : " << in.second << std::endl;
    return 0;
}

Ввод

input:  dict = {
            "Key1" : "1.f",
            "Key2" : {
                "a" : "2",
                "b" : "3",
                "c" : {
                    "d" : "3",
                    "e" : {
                        "" : "1"
                    }
                }
            }
        }

Вывод

/*
output
Key1 : 1065353216
Key2.a : 2
Key2.b : 3
Key2.c.d : 3
Key2.c.e. : 1
/*
→ Ссылка