C++ 如何声明引用自身的typedef?
我有一个变量类型,我想在JSON解析器中使用它。JSON中的类型可以包括对象和数组。这些对象和数组可以包含其自己类型的成员: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
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