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应该可以工作吗?