0

有谁知道将模板专业化与复合结构中使用的自定义类一起使用的方法?

具体来说,我正在编写一个程序来解析/验证 XML 文档,其中 XML 数据存储在自定义复合树结构中,该结构使用我的class XMLNode数据结构构建,如下所示。

每个 XMLNode 对象都在其std::unordered_set<XMLNode> children成员中存储子节点,我想使用std::hash结构的模板专门化,以便可以使用 XMLNode 对象的专用散列函数插入新节点。这是我到目前为止所拥有的:

    #include <string>
    #include <unordered_map>
    #include <forward_list>
    #include <unordered_set>

    class XMLNode {

    private:

        std::string element_name;
        std::forward_list<std::string> content;
        std::unordered_map<std::string, std::string> attributes;
        **std::unordered_set<XMLNode> children;**

    public:

        // default constructor - sets member variables to empty containers and parent pointer to NULL.
        XMLNode() : element_name(), content(), attributes(), children() {};

        // copy constructor
        XMLNode(const XMLNode & node) : element_name(node.element_name), content(node.content), attributes(node.attributes), children(node.children) {};

        // destructor - members of the object are automatically emptied and freed when object passes out of scope.
        ~XMLNode() {};

        // copy assignment operator - deep copy
        XMLNode & operator = (const XMLNode & rhs)
        {
            element_name = rhs.element_name;
            content = rhs.content;
            attributes = rhs.attributes;
            children = rhs.children;
            return *this;
        };

        // compare two nodes are equal (have equal names and attributes)
        bool operator ==(const XMLNode & comparison_node) const
        {
            return (element_name == comparison_node.element_name && attributes == comparison_node.attributes);
        };

        const std::string & get_name() const
        {
            return element_name;
        };

    };

    namespace std
    {
        template<>
        **struct hash<XMLNode>**
        {
            size_t
                operator()(const XMLNode & obj) const
            {
                return hash<string>()(obj.get_name()); // implementation not finalised.
            }
        };
    }

    int main() 
    {
        return 0;
    }

然而,编译器对此存在问题,因为XMLNode该类依赖于std::hash<XMLNode(因为std::unordered_set<XMLNode> children)并且std::hash<XMLNode需要class XMLNode首先定义。

具体来说,使用 VS 15.4.4 编译时出现以下错误:E1449 explicit specialization of class "std::hash<XMLNode>" must precede its first use (at line 575 of "c:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\include\type_traits")

但是,将定义放在std::hash<XMLNode>定义之前XMLNode并转发声明XMLNode类也不能提供解决方案。

有没有人有这个问题的设计解决方案?或者这在 C++ 中是不可行的?谢谢。

4

1 回答 1

0

只需首先声明您的类,然后定义。沿着这些思路(未测试):

class XMLNode;

namespace std {
  template<>
  struct hash<XMLNode> {
    size_t operator()(const XMLNode & obj) const;
  };
}

class XMLNode {
  /* actual definition here */
};

size_t std::hash<XMLNode>::operator()(const XMLNode & obj) const {
  /* actual definition here */
}
于 2018-02-15T14:35:22.850 回答