'Cannot auto-complete for map iterator in cross-referenced class templates

I am writing some C++ code where I have a few class templates that cross reference each other (if I understand these words correctly). One of the class contains a map container, and I cannot get auto-completion to work for the map iterator when I use it in a member function of another class, either in JetBrain CLion or VS Code.

Below is a minimal working example, the code compiles and runs fine. I use the pattern ***** to highlight some for loops and whether the auto-completion works or not. As you can see, the position of the class declaration also matters. I guess template deduction is hard?

I would sincerely appreciate it a lot if someone can explain the reasons behind them and what I should do to make auto-completion work.

#include <iostream>
#include <map>

template <int D> class Planet;
template <int D> class PlanetList;
template <int D> class BHtree;
template <class T, int D> class DataSet;

/* In addition, if I move the declaration of BHtree before other classes, both cannot auto-complete
 ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****
    ...
    for (auto &it : ds.planet_list.planets) {
        std::cout << it.second.mass; // <== still cannot auto-complete after typing it or it.second
    }
    ...
    for (auto it = ds.planet_list.planets.begin(); it != ds.planet_list.planets.end(); it++) {
        std::cout << it->second.mass; // <== cannot auto-complete after typing it or it->second
    }
    ...
 ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****
 */

template <int D> class Planet {
public:
    double mass {0};
    double pos[D];
};

template <int D> class PlanetList {
public:
    uint32_t num_planets{0};
    std::map<uint32_t, Planet<D>> planets;
};

template <class T, int D> class DataSet {
public:
    BHtree<D> tree;
    PlanetList<D> planet_list;
};


template <int D>
class BHtree {
public:
    struct TreeNode {
        double pos[D];
    };
    TreeNode *tree;

    template <class T, class F>
    void FindPlanet(DataSet<T, D> &ds, F DensityKernel, int loop_count) {
        //***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****
        for (auto &it : ds.planet_list.planets) {
            std::cout << it.second.mass; // <== Cannot auto-complete after typing it or it.second
        }
        std::cout << std::endl;
        for (auto it = ds.planet_list.planets.begin(); it != ds.planet_list.planets.end(); it++) {
            std::cout << it->second.mass; // <== This, however, can auto-complete for it and it->second
        }
        std::cout << std::endl;
        //***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****
    }
};

constexpr int dim {3};

int main()
{
    DataSet<float, dim> ds;
    ds.tree.tree = new BHtree<dim>::TreeNode[2];

    ds.planet_list.planets.emplace(0, Planet<dim>());
    ds.planet_list.planets.emplace(1, Planet<dim>());

    //***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****
    for (auto &it : ds.planet_list.planets) {
        std::cout << it.second.mass << std::endl; // <== auto-complete without issue for it and for it.second
    }
    //***** ***** ***** ***** ***** ***** ***** ***** ***** ***** ***** *****
    ds.tree.FindPlanet(ds, nullptr, 0);

    return 0;
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source