Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.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++ std::包含自身的容器的变体_C++_Stl_C++17_Variant - Fatal编程技术网

C++ std::包含自身的容器的变体

C++ std::包含自身的容器的变体,c++,stl,c++17,variant,C++,Stl,C++17,Variant,我有一种二进制格式,我正在为它编写编码器和解码器。几乎所有的二进制类型都直接映射到原语,除了两种容器类型,一种是列表类型,另一种是映射类型,可以包含格式中的任何其他类型,包括它们自己 他们觉得自己只是想成为std::variant typedef std::variant ListType 但因为我需要能够包含ListType本身的向量,所以我最终会这样做 struct ListType{ std::变量值; } 这为使用该类型增加了一点摩擦。实际上,这些变量没有其他状态来证明封装它们的合理

我有一种二进制格式,我正在为它编写编码器和解码器。几乎所有的二进制类型都直接映射到原语,除了两种容器类型,一种是列表类型,另一种是映射类型,可以包含格式中的任何其他类型,包括它们自己

他们觉得自己只是想成为
std::variant

typedef std::variant ListType
但因为我需要能够包含ListType本身的向量,所以我最终会这样做

struct ListType{
std::变量值;
}
这为使用该类型增加了一点摩擦。实际上,这些变量没有其他状态来证明封装它们的合理性

把它打出来,我意识到我在问“你能向前声明一个模板吗?”这似乎是一个愚蠢的问题。不过,有谁有更好的策略吗?

模板
template<class...Ts>
struct self_variant;

template<class...Ts>
using self_variant_base = 
  std::variant<
    std::vector<Ts>...,
    std::vector<self_variant<Ts...>>
  >;


template<class...Ts>
struct self_variant:
  self_variant_base<Ts...>
{
  using self_variant_base<Ts...>::self_variant_base;
  self_variant_base<Ts...> const& base() const { return *this; }
  self_variant_base<Ts...>& base() { return *this; }
};

template<class T>
void print( T const& t ) {
    std::cout << t << ",";
}
template<class T>
void print( std::vector<T> const& v ) {
    std::cout << "[";
    for (auto const& e:v) {
        print(e);
    }
    std::cout << "]\n";
}
template<class...Ts>
void print( self_variant<Ts...> const& sv ) {
    std::visit( [](auto& e){
        print(e);
    }, sv.base());
}

int main() {
    self_variant<int, char> bob = std::vector<int>{1,2,3};
    self_variant<int, char> alice = std::vector<self_variant<int, char>>{ bob, bob, bob };
    print(alice);
}
结构自变异; 模板 使用自_变量_基= std::变体< 向量。。。, 向量 >; 模板 结构自变量: 自变异基 { 使用自变量库::自变量库; self_variant_base const&base()const{return*this;} self_variant_base&base(){return*this;} }; 模板 无效打印(T常量和T){ std::cout
模板
结构自变异;
模板
使用自_变量_基=
std::变体<
向量。。。,
向量
>;
模板
结构自变量:
自变异基
{
使用自变量库::自变量库;
self_variant_base const&base()const{return*this;}
self_variant_base&base(){return*this;}
};
模板
无效打印(T常量和T){

std::cout似乎相关:这只是C++设计中的一个基本盲点,没有更干净的解决办法。@SamVarshavchik这就是我所怀疑的,谢谢你的帮助。似乎相关:这只是C++设计中的一个基本盲点,没有更干净的解决办法。@SamVarshavchik这就是我所怀疑的,谢谢你的帮助吗?不幸的是,我需要包含只有在运行时才知道的任意嵌套深度的嵌套变体。除非我遗漏了什么,否则这在这里是不可能的?例如,我可能需要一个充满alice的alice,或者一个交替Bob和alice的alice。@nickelpro正是这样做的。请参阅@nickelpro以获得需要堆内存的任意深度y、 一个简单的方法是使用一个
std::unique\u ptr
,它可以保存一个变体,就像
std::unique\u ptr
@Ben一样,不幸的是,这使得复制类型非常令人沮丧,代码也非常繁重。我在这个问题中阐述了我的观点,因为我需要一个可以与
std::map
一起工作的解决方案well@nick我不明白你为什么要这么做你说复制令人沮丧?默认的ctor/assign应该可以工作?不幸的是,我需要包含只有在运行时才知道的任意嵌套深度的嵌套变体。除非我遗漏了什么,否则这在这里是不可能的?例如,我可能需要一个充满alice的alice,或者一个交替Bob和alice的alice。@nickelpro这是一个例子确实如此。请看@nickelpro以获得任意深度,您需要堆内存。一个简单的方法是使用
std::unique_ptr
,它可以保存一个变量,如
std::unique_ptr
。@Ben不幸的是,这使得复制类型非常令人沮丧,代码也非常繁重。我在问题中阐述了这一点,因为我需要一个可行的解决方案使用
std::map
aswell@nick我不明白你为什么说复制令人沮丧?默认的ctor/assign应该可以工作吗?