C++ C++;17使用std::variant表示DOM

C++ C++;17使用std::variant表示DOM,c++,dom,c++17,variant,C++,Dom,C++17,Variant,我试图学习如何使用C++17中的std::variant。例如,我们开始使用它来表示DOM。尽管这项工作仍在进行中: 我想就std::variant 还有一些关于编译器的输入支持 我有DOM表示代码(),它似乎可以很好地编译。但是,我看到相同的代码不能用编译 我想了解这种不兼容的原因是什么。还有,是否有人可以对“样式”发表评论,以及这是否是std::variant的适当用法 #include <vector> #include <type_traits> #include

我试图学习如何使用C++17中的
std::variant
。例如,我们开始使用它来表示DOM。尽管这项工作仍在进行中:

  • 我想就
    std::variant
  • 还有一些关于编译器的输入支持
  • 我有
    DOM表示代码
    (),它似乎可以很好地编译。但是,我看到相同的代码不能用编译

    我想了解这种不兼容的原因是什么。还有,是否有人可以对“样式”发表评论,以及这是否是
    std::variant
    的适当用法

    #include <vector>
    #include <type_traits>
    #include <string>
    #include <variant>
    #include <unordered_map>
    
    // https://dom.spec.whatwg.org/ : reference for the DOM.
    
    namespace dragon {
        namespace dom {
            namespace traits_ns {
                template <bool valid_node_type = false>
                struct valid_node {
                    static constexpr bool value = valid_node_type;
                };
    
                template <typename T>
                struct is_valid_node {
                    static constexpr bool value = std::is_base_of<valid_node<true>, T>::value && T::value;
                };
    
                // TODO: Need to define policy concepts which will check if the children 
                // of each node is of the right, allowed type.
            }
    
            struct Element;
            struct Text;
            struct Document;
            struct Document_type;
            struct Document_fragment;
            struct Processing_instruction;
            struct Comment;
    
            using AttrList = std::vector<std::pair<std::string, std::string>>;
            using AttrSet = std::unordered_map<std::string, std::string>;
            using Node = std::variant<Document, Document_type, Document_fragment, Element, Text, Processing_instruction, Comment>;
            using Children = std::vector<Node>;
    
    
            struct Element final : traits_ns::valid_node<true> {
                Element(std::string t, const Children& c, const AttrList& a) : tag{ t }, child{ c } {}
                Element() = default;
                ~Element() = default;
                std::string tag;
                Children child;
                AttrSet attr;
            };
    
            struct Text final : traits_ns::valid_node<true> {
                explicit Text(std::string d) : data{ d } {}
                std::string data;
            };
    
            struct Document final : traits_ns::valid_node<true> {
                Document() = default;
                ~Document() = default;
            };
    
            struct Document_type final : traits_ns::valid_node<true> {};
            struct Document_fragment final : traits_ns::valid_node<true> {};
            struct Processing_instruction final : traits_ns::valid_node<true> {};
            struct Comment final : traits_ns::valid_node<true> {};
    
        } // namespace dom
    } // namespace dragon
    
    
    namespace dom = dragon::dom;
    using std::vector;
    
    int main()
    {
        dom::Node t{dom::Text{"Hello"}};
        dom::Node e{dom::Element{"element", {}, {{"class", "blah"}}}};
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    // https://dom.spec.whatwg.org/ :DOM的引用。
    名称空间龙{
    名称空间dom{
    名称空间特性{
    模板
    结构有效\u节点{
    静态constexpr bool value=有效节点类型;
    };
    模板
    结构是有效的节点{
    静态constexpr bool value=std::是::value和&T::value的基础;
    };
    //TODO:需要定义策略概念,以检查子项
    //每个节点的类型都是正确的、允许的类型。
    }
    结构元素;
    结构文本;
    结构文档;
    结构文档类型;
    结构文档_片段;
    结构处理指令;
    结构注释;
    使用AttrList=std::vector;
    使用AttrSet=std::无序映射;
    使用Node=std::variant;
    使用Children=std::vector;
    结构元素final:traits\u ns::valid\u节点{
    元素(std::string t,const Children&c,const AttrList&a):标记{t},子{c}{
    元素()=默认值;
    ~Element()=默认值;
    std::字符串标签;
    儿童;
    属性集属性;
    };
    结构文本final:traits\u ns::valid\u节点{
    显式文本(std::string d):数据{d}{
    std::字符串数据;
    };
    结构文档最终版本:traits\u ns::valid\u节点{
    Document()=默认值;
    ~Document()=默认值;
    };
    结构文档类型final:traits\u ns::valid\u node{};
    结构文档\u片段final:traits\u ns::valid\u node{};
    结构处理_指令final:traits_ns::valid_node{};
    结构注释final:traits_ns::valid_node{};
    }//名称空间dom
    }//名称空间龙
    名称空间dom=dragon::dom;
    使用std::vector;
    int main()
    {
    dom::Node t{dom::Text{“Hello”};
    dom::Node e{dom::Element{“Element”,{},{{{“class”,“blah”}};
    返回0;
    }
    
    GCC产生的错误片段:

            #1 with x86-64 gcc (trunk)
    
        In file included from /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/move.h:55:0,
                         from /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/stl_pair.h:59,
                         from /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/stl_algobase.h:64,
                         from /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/vector:60,
                         from <source>:1:
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/type_traits: In instantiation of 'struct std::is_trivially_destructible<dragon::dom::Document>':
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/type_traits:2859:25:   required from 'constexpr const bool std::is_trivially_destructible_v<dragon::dom::Document>'
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:309:5:   required from 'constexpr const bool std::__detail::__variant::_Traits<dragon::dom::Document, dragon::dom::Document_type, dragon::dom::Document_fragment, dragon::dom::Element, dragon::dom::Text, dragon::dom::Processing_instruction, dragon::dom::Comment>::_S_trivial_dtor'
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:317:20:   required from 'constexpr const bool std::__detail::__variant::_Traits<dragon::dom::Document, dragon::dom::Document_type, dragon::dom::Document_fragment, dragon::dom::Element, dragon::dom::Text, dragon::dom::Processing_instruction, dragon::dom::Comment>::_S_trivial_move_assign'
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:642:16:   required by substitution of 'template<class ... _Types> using _Move_assign_alias = std::__detail::__variant::_Move_assign_base<std::__detail::__variant::_Traits<_Types>::_S_trivial_move_assign, _Types ...> [with _Types = {dragon::dom::Document, dragon::dom::Document_type, dragon::dom::Document_fragment, dragon::dom::Element, dragon::dom::Text, dragon::dom::Processing_instruction, dragon::dom::Comment}]'
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:645:12:   required from 'struct std::__detail::__variant::_Variant_base<dragon::dom::Document, dragon::dom::Document_type, dragon::dom::Document_fragment, dragon::dom::Element, dragon::dom::Text, dragon::dom::Processing_instruction, dragon::dom::Comment>'
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:1032:11:   required from 'class std::variant<dragon::dom::Document, dragon::dom::Document_type, dragon::dom::Document_fragment, dragon::dom::Element, dragon::dom::Text, dragon::dom::Processing_instruction, dragon::dom::Comment>'
        41 : <source>:41:86:   required from here
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/type_traits:1285:12: error: invalid use of incomplete type 'struct dragon::dom::Document'
             struct is_trivially_destructible
                    ^~~~~~~~~~~~~~~~~~~~~~~~~
        28 : <source>:28:10: note: forward declaration of 'struct dragon::dom::Document'
           struct Document;
                  ^~~~~~~~
        In file included from /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/move.h:55:0,
                         from /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/stl_pair.h:59,
                         from /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/stl_algobase.h:64,
                         from /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/vector:60,
                         from <source>:1:
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/type_traits: In instantiation of 'constexpr const bool std::is_trivially_destructible_v<dragon::dom::Document>':
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:309:5:   required from 'constexpr const bool std::__detail::__variant::_Traits<dragon::dom::Document, dragon::dom::Document_type, dragon::dom::Document_fragment, dragon::dom::Element, dragon::dom::Text, dragon::dom::Processing_instruction, dragon::dom::Comment>::_S_trivial_dtor'
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:317:20:   required from 'constexpr const bool std::__detail::__variant::_Traits<dragon::dom::Document, dragon::dom::Document_type, dragon::dom::Document_fragment, dragon::dom::Element, dragon::dom::Text, dragon::dom::Processing_instruction, dragon::dom::Comment>::_S_trivial_move_assign'
    
    <SNIP> 
    
    dragon::dom::Document_fragment, dragon::dom::Element, dragon::dom::Text, dragon::dom::Processing_instruction, dragon::dom::Comment}]' is implicitly deleted because the default definition would be ill-formed:
               variant(const variant& __rhs) = default;
               ^~~~~~~
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:1087:7: error: use of deleted function 'constexpr std::_Enable_copy_move<false, false, false, false, _Tag>::_Enable_copy_move(const std::_Enable_copy_move<false, false, false, false, _Tag>&) [with _Tag = std::variant<dragon::dom::Document, dragon::dom::Document_type, dragon::dom::Document_fragment, dragon::dom::Element, dragon::dom::Text, dragon::dom::Processing_instruction, dragon::dom::Comment>]'
        In file included from /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:38:0,
                         from <source>:4:
        /opt/compiler-explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/enable_special_members.h:301:15: note: declared here
             constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
                       ^~~~~~~~~~~~~~~~~
        Compiler exited with result code 1
    
            x86-64 gcc (trunk) (Editor #1, Compiler #1)
    
        g++ (GCC-Explorer-Build) 8.0.0 20171009 (experimental)- cached
    
    带有x86-64 gcc(主干)的
    #1
    在/opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/move.h:55:0中包含的文件中,
    来自/opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/stl_pair.h:59,
    来自/opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/stl_algobase.h:64,
    来自/opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/vector:60,
    发件人:1:
    /opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/type_traits:在“struct std::is_minally_destructible”的实例化中:
    /opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/type_traits:2859:25:“constexpr const bool std::is_minally_destructible_v”中必需的
    /opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:309:5:来自“constexpr const bool std::”的必填项详细信息::u变量::_特征::_S_平凡的_dtor'
    /opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:317:20:来自“constexpr const bool std::”的必填项详细信息::。。。。变量::
    /opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:642:16:替换“使用移动分配别名=std的模板”时需要::\uuuu详细信息::\uu变量::\uu移动分配分配基础[使用类型={dragon::dom::Document,dragon::dom::Document\u类型,dragon::dom::Document\u片段,dragon::dom::Element,dragon::dom::Text,dragon::dom::Processing\u指令,dragon::dom::Comment}'
    /opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:645:12:从“struct std:\ \详细信息:\ \变量:\ \变量\基础”中需要
    /opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:1032:11:必须来自“class std::variant”
    41::41:86:从这里开始需要
    /opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/type_traits:1285:12:错误:无效使用不完整的类型“struct dragon::dom::Document”
    结构是可破坏的
    ^~~~~~~~~~~~~~~~~~~~~~~~~
    28::28:10:注意:“struct dragon::dom::Document”的转发声明
    结构文档;
    ^~~~~~~~
    在/opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/move.h:55:0中包含的文件中,
    来自/opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/stl_pair.h:59,
    来自/opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/bits/stl_algobase.h:64,
    来自/opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/vector:60,
    发件人:1:
    /opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/type_traits:在“constexpr const bool std::is_minally_destructible_v”的实例化中:
    /opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:309:5:来自“constexpr const bool std::”的必填项详细信息::u变量::_特征::_S_平凡的_dtor'
    /opt/compiler explorer/gcc-trunk-20171009/include/c++/8.0.0/variant:317:20:来自“constexpr const bool std::”的必填项详细信息::。。。。变量::
    dragon::dom::Document_片段,dragon::dom::元素,dragon::
    
    #include <vector>
    #include <type_traits>
    #include <string>
    #include <variant>
    #include <unordered_map>
    
    // https://dom.spec.whatwg.org/ : reference for the DOM.
    
    namespace dragon {
        namespace dom {
            namespace traits_ns {
                template <bool valid_node_type = false>
                struct valid_node {
                    static constexpr bool value = valid_node_type;
                };
    
                template <typename T>
                struct is_valid_node {
                    static constexpr bool value = std::is_base_of<valid_node<true>, T>::value && T::value;
                };
    
                // TODO: Need to define policy concepts which will check if the children 
                // of each node is of the right, allowed type.
            }
    
            struct Element;
            struct Text;
            struct Document;
            struct Document_type;
            struct Document_fragment;
            struct Processing_instruction;
            struct Comment;
    
            using AttrList = std::vector<std::pair<std::string, std::string>>;
            using AttrSet = std::unordered_map<std::string, std::string>;
            using Node = std::variant<Document, Document_type, Document_fragment, Element, Text, Processing_instruction, Comment>;
            using Children = std::vector<Node>;
    
    
            struct Element final : traits_ns::valid_node<true> {
                Element(std::string t, const Children& c, const AttrList& a);
                Element() = default;
                ~Element() = default;
                std::string tag;
                Children child;
                AttrSet attr;
            };
    
            struct Text final : traits_ns::valid_node<true> {
                explicit Text(std::string d) : data{ d } {}
                std::string data;
            };
    
            struct Document final : traits_ns::valid_node<true> {
                Document() = default;
                ~Document() = default;
            };
    
            struct Document_type final : traits_ns::valid_node<true> {};
            struct Document_fragment final : traits_ns::valid_node<true> {};
            struct Processing_instruction final : traits_ns::valid_node<true> {};
            struct Comment final : traits_ns::valid_node<true> {};
    
            Element::Element(std::string t, const Children& c, const AttrList& a) : tag{ t }, child{ c } {}
    
        } // namespace dom
    } // namespace dragon
    
    
    namespace dom = dragon::dom;
    using std::vector;
    
    int main()
    {
        dom::Node t{dom::Text{"Hello"}};
        dom::Node e{dom::Element{"element", {}, {{"class", "blah"}}}};
        return 0;
    }