如何声明引用自身的typedef? [英] How to declare a typedef that references itself?
问题描述
我有一个Variant类型,我想在像JSON解析器的东西使用。 JSON中的类型可以包括对象和数组。这些对象和数组可以包含自己类型的成员:
I have a Variant type which I want to use in something like a JSON parser. A type in JSON can include objects and arrays. These objects and arrays can contain members of their own type:
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.
如何创建一个递归模板类型?
How do I create a "recursive" templated type?
类似:
typedef variant<int,float,bool,std::string,std::vector<type>,std::unordered_map<std::string,type> type;
我知道boost;我对使用它的答案不感兴趣。我试图找出它如何做它与 recursive_wrapper
但是,自由使用预处理器宏是使我非常困难。
I'm aware of boost; I'm not interested in answers that use it. I've tried to work out how it does it with recursive_wrapper
but the liberal use of pre-processor macros is making it very hard for me.
EDIT
在Yakk的帮助下,我已经走得很远:
With the help of Yakk below, I've gotten this far:
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;
};
实际的Variant类型是这里 http://codereview.stackexchange.com/questions/127372/variant-class-that-i-dont-think -is-missing-anything
The actual Variant type I have is here http://codereview.stackexchange.com/questions/127372/variant-class-that-i-dont-think-is-missing-anything
我认为上述 RecursiveWrapper
是关闭的。根据我的理解,我应该使用它作为实际类型,即
I think the above RecursiveWrapper
is way off. As I understand it, I should use it as the actual type, i.e.
RecursiveWrapper<RecursiveType> Variant
但是,这不能正确,因为我没有指定 Variant
。关于代码的问题我不明白是
However, this can't be correct because nowhere have I specified the types allowed in Variant
. Questions about the code I don't understand are
- 什么是
RecursiveType
? - 如何将可变参数模板类型转移到底层
Variant
?
- What is
RecursiveType
? - How can I forward variadic template types to the underlying
Variant
?
推荐答案
我将使用boost变量,特别是 http://www.boost.org/doc/libs/1_61_0/doc/html/boost/make_recursive_variant.html 以及 http://www.boost.org /doc/libs/1_61_0/doc/html/variant/tutorial.html#variant.tutorial.recursive.recursive-variant
I would use boost variant, in particular see http://www.boost.org/doc/libs/1_61_0/doc/html/boost/make_recursive_variant.html and http://www.boost.org/doc/libs/1_61_0/doc/html/variant/tutorial.html#variant.tutorial.recursive.recursive-variant
这篇关于如何声明引用自身的typedef?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!