具有boost :: variant的灵活层次结构

时间:2016-07-09 17:49:41

标签: c++ boost variant

问题是@sehe as part of his answer to my previous question提供的修改后的代码。此修改包括每个节点的父节点。样品结构是Store-> Shelves-> Products。我想在每个节点中拥有父级。代码编译得很好,但节点的“父”成员显然已被破坏。我会很感激帮助找出原因。谢谢!

    #include <iostream>
    #include <sstream>
    #include <algorithm>
    #include <string>
    #include <vector>
    #include <boost/variant.hpp>
    #include <boost/format.hpp>

    namespace GenericDomain {

        namespace Tag {
            struct Store{};
            struct Shelf{};
            struct Product{};
        }

        template <typename Kind> struct Node;

        using Store = Node<Tag::Store>;
        using Shelf = Node<Tag::Shelf>;
        using Product = Node<Tag::Product>;

        using Tree = boost::variant<
            boost::recursive_wrapper<Product>,
            boost::recursive_wrapper<Store>,
            boost::recursive_wrapper<Shelf>
        >;

        template <typename Kind> struct Node {
            std::string name;
            std::vector<Tree> children;
            Kind kind;
            Tree* parent;
            Node(std::string ofname, Tree* ofparent) : name(ofname), parent(ofparent) {}
        };

        std::ostream& operator<<(std::ostream& os, Tag::Store)   { return os << "Store"; }
        std::ostream& operator<<(std::ostream& os, Tag::Shelf)   { return os << "\tShelf"; }
        std::ostream& operator<<(std::ostream& os, Tag::Product) { return os << "\t\tProduct"; }

        struct vstName : public boost::static_visitor<const std::string&>
        {
            template<typename T> const std::string& operator()(T& p) const {
                return p.name;
            }
        };

        template <typename Kind> std::ostream& operator<<(std::ostream& os, Node<Kind> const& n) {
            os << Kind{} << ": " << n.name << "\n";
            if (n.parent == nullptr)
                os << "root\n";
            else {
                vstName visitorName;
                std::string parentname = boost::apply_visitor(visitorName, *n.parent);
                os << "parent of " << parentname << "\n";
            }
            for (auto& child : n.children) os << child;
            return os;
        }

        std::string test1()
        {
            std::vector<Tree> stores;
            for (int s = 0; s < 2; ++s)
            {
                stores.emplace_back(Tree(Store((boost::format("store %1%") % s).str(), nullptr)));
                Tree& store = *stores.rbegin();
                std::vector<Tree>& shelves = boost::get<Store>(store).children;
                for (int sh = 0; sh < 2; ++sh) {
                    shelves.push_back(Tree(Shelf((boost::format("shelf %1%-%2%") % s %sh).str(), &store)));
                    Tree& shelf = *shelves.rbegin();
                    std::vector<Tree>& products = boost::get<Shelf>(shelf).children;
                    for (int pr = 0; pr< 2; ++pr) 
                        products.push_back(Tree(Product((boost::format("product %1%-%2%-%3%") % s %sh %pr).str(), &shelf)));
                }
            }

            std::ostringstream oss;
            std::for_each(begin(stores), end(stores),
                [&](const Tree& p){oss << p; });
            return oss.str();
        }

    };
int main(int argc, char *argv[])
{
    std::cout << GenericDomain::test1();
    return 1;
}

0 个答案:

没有答案