Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何声明引用自身的typedef?_C++_Templates_C++11_Variadic Templates_Generic Programming - Fatal编程技术网

C++ 如何声明引用自身的typedef?

C++ 如何声明引用自身的typedef?,c++,templates,c++11,variadic-templates,generic-programming,C++,Templates,C++11,Variadic Templates,Generic Programming,我有一个变量类型,我想在JSON解析器中使用它。JSON中的类型可以包括对象和数组。这些对象和数组可以包含其自己类型的成员: typedef variant<int,float,bool,std::string> baseType; typedef std::vector<baseType> arrayType; // problem, can't have arrays of arrays typedef std::unordered_map<std::strin

我有一个变量类型,我想在JSON解析器中使用它。JSON中的类型可以包括对象和数组。这些对象和数组可以包含其自己类型的成员:

typedef variant<int,float,bool,std::string> baseType;
typedef std::vector<baseType> arrayType; // problem, can't have arrays of arrays
typedef std::unordered_map<std::string,baseType> objType; // problem, can't have objects or arrays within objects.
我的实际变体类型在这里

我认为上面的
RecursiveWrapper
已经过时了。据我所知,我应该使用它作为实际类型,即

RecursiveWrapper<RecursiveType> Variant
RecursiveWrapper变量
但是,这不可能是正确的,因为我没有在
Variant
中指定允许的类型。关于我不理解的代码的问题是

  • 什么是递归类型
  • 如何将可变模板类型转发到基础的
    变量

  • 我会使用boost变体,尤其是see和

    ,看起来你把模板和容器混淆了。“数组数组”看起来像
    std::vector
    。这将是一个字符串数组数组。你能详细解释一下为什么你的问题中的
    变量
    是模板化的吗?对不起,我认为这是显而易见的<代码>变量
    是模板化的,因为它将允许其保存的类型作为模板参数。为了保存自身的容器,typedef需要能够引用自身,以便容器类型,
    vector
    unordered\u map
    能够包含相同的类型。那可能很清楚。我还是不明白你为什么要那样做。您是否希望相同的代码适用于其他类型的变体?是的。另一种方法是每次我需要一个新的组合变量时创建一个类层次结构和指针类型。你是真的在尝试编写JSON解析器,还是只是希望用它来做其他事情?如果是后者,则有经过良好测试的库,如Jansson,用于解析JSON()。它们可能并不完全是你想要的,但总的来说你可能会节省时间。我不想依赖boost。但我是在看它们的实施情况吗
    template<typename... Ts>
    class Variant;
    
    template<class T>
    struct tag
    {
        using type=T;
    };
    
    template<class X, class A, class B>
    struct subst : tag<X>
    {};
    
    template<class X, class A, class B>
    using subst_t = typename subst<X,A,B>::type;
    
    template<class A, class B>
    struct subst<A,A,B> : tag<B>
    {};
    
    template<class X, class A, class B>
    struct subst<X&,A,B> : tag<subst_t<X,A,B>&>
    {};
    
    template<class X, class A, class B>
    struct subst<X&&,A,B> : tag<subst_t<X,A,B>&&>
    {};
    
    template<class X, class A, class B>
    struct subst<X const,A,B> : tag<subst_t<X,A,B>const>
    {};
    
    template<class X, class A, class B>
    struct subst<X volatile,A,B> : tag<subst_t<X,A,B>volatile>
    {};
    
    template<class X, class A, class B>
    struct subst<X const volatile,A,B> : tag<subst_t<X,A,B>const volatile>
    {};
    
    template<template<class...> class Z, class... Xs, class A, class B>
    struct subst<Z<Xs...>,A,B> : tag<Z<subst_t<Xs,A,B>...>>
    {};
    
    template<template<class,size_t> class Z, class X, size_t n, class A, class B>
    struct subst<Z<X,n>,A,B> : tag<Z<subst_t<X,A,B>,n>>
    {};
    
    template<class R, class...Xs, class A, class B>
    struct subst<R(Xs...),A,B> : tag<subst_t<R,A,B>(subst_t<Xs,A,B>...)>
    {};
    
    struct RecursiveType {};
    
    template<typename Sig>
    struct RecursiveVariant
    {
        using VariantType = Variant<subst_t<Sig,RecursiveType,RecursiveVariant>>;
    
        template<typename V,
            typename std::enable_if<
                !std::is_same<RecursiveVariant,typename std::decay<V>::type>::value
                && std::is_convertible<V,VariantType>::value
            >
        ::type>
        RecursiveVariant(V&& vIn)
        :
            m_variant(vIn)
        {}
    
        RecursiveVariant(){};
    
    
        template<typename T, typename... Args>
        void Set(Args&&... args)
        {
            m_variant.Set<T,Args...>(std::forward<Args>(args)...);
        }
    
        template<typename T>
        const T& Get() const
        {
            return m_variant.Get<T>();
        }
    
        template<typename T>
        T& Get()
        {
            return m_variant.Get<T>();
        }
    
        VariantType m_variant;
    };
    
    RecursiveWrapper<RecursiveType> Variant