尼斯特布尔向量类
Nestable Vector Class
我正在做一个项目,我需要能够拥有一种特定的数据结构。从本质上讲,我需要能够有一个向量,它可以存储整数作为元素,或者另一个向量。然后同样的想法需要应用于第二个向量。我知道这相当于让容器包含自身,但我想知道是否有某种方法可以做到这一点。
也许一个例子会澄清。我希望能够拥有这样的集合:
[[1,2], [[3,4], 5], [6, 7]]
我的想法是我可以无限深入地在"系列"和"并行"处进行整数和向量。我知道这是一个艰难的问题,但有什么办法可以做到这一点。我的一个想法是,我们可以有一个向量,其中 Elem 是我们定义的一个类,其中包含一个表示其嵌套深度的 int,以及一个指向堆分配元素的 void* 指针。
我觉得这里有一些多态魔法可以完成,但不太确定。
一些提升魔法怎么样?
#include <vector>
#include <boost/variant.hpp>
#include <boost/variant/recursive_wrapper.hpp>
// A recursive tree structure made of std::vector.
template< typename T, class Allocator = std::allocator<T> >
struct vector_tree :
std::vector<
boost::variant< T, boost::recursive_wrapper< vector_tree< T, Allocator > > >,
Allocator >
{
using base = std::vector<
boost::variant< T, boost::recursive_wrapper< vector_tree< T, Allocator > > >,
Allocator >;
// Forward all constructors of the base class.
using base::base;
};
此类型允许无限嵌套,并具有非常干净的初始化语法。
使用示例
using mytree = vector_tree<int>;
// Construct a nested vector_tree with initializer list.
mytree tree{
1,
2,
mytree{
mytree{ 3, 4, 5 },
6,
}
};
// Add more stuff.
tree.push_back( 42 );
tree.push_back( mytree{ 43, 44 } );
// Add something to a child vector_tree.
// NOTE: boost::get() will throw a boost::bad_get exception if requested type is invalid
boost::get<mytree>( tree[ 2 ] ).push_back( 99 );
// To avoid the boost::bad_get exception, we can check if the child actually is a vector_tree:
if( mytree* pchild = boost::get<mytree>( &tree[ 2 ] ) )
{
(*pchild)[ 1 ] = 88;
}
科利鲁的现场演示。
解释
boost::recursive_wrapper
是必需的,因为boost::variant
通常需要完整的类型,但在声明时vector_tree
仍然不完整。
boost::recursive_wrapper
实际上没什么魔术。它只是一个指针的包装器!众所周知,可以为不完整的类型声明指针而不会出现问题。这个包装类只是隐藏了通过处理分配、释放和提供值语义来使用指针的事实。它具有boost::variant
的特殊支持,使包装器完全透明,因此可以像根本没有包装器类一样使用该变体。
注意:自 C++17 以来,有std::variant
但 AFAIK 没有可以透明处理嵌套的boost::recursive_wrapper
等效项。
如果你想使用多态性,你可以定义一个基struct
,并从中派生一个包含std::vector<*base>
的结构,并派生另一个包含int
的结构。main 函数将包含第一个派生类的实例,该实例可能包含指向自身的指针,或第二个派生类。这将允许包含 int 的向量中的向量。
若要存储深度等信息,可以在基结构中有一个int depth
,构造函数将在其中传递当前深度并添加一个深度。
以下是您要查找的内容:
template <typename T>
class NestableVector {
private:
struct element {
virtual element* copy() const = 0;
};
struct vector_element : public element {
NestableVector value;
element* copy() const;
};
struct normal_element : public element {
T value;
element* copy() const;
};
class copy_ptr { // specialized smart pointer that copies underlying object when copied
private:
element* ptr;
public:
copy_ptr(element*);
copy_ptr(const copy_ptr&); // copies *ptr into new object
void operator=(const copy_ptr&); // same as above
};
std::vector<copy_ptr> v; // underlying vector
public:
// interface to v here
};
定义具有两个子类(vector_element
和normal_element
)的特殊element
类型。这两者都重载基类的copy()
函数,该函数用于新的智能指针类copy_ptr
,该函数复制复制时它本身指向的元素。我们使用智能指针,以便在v
中复制内容时,元素本身被复制,而不是指向它们的指针。
- 布尔值向量的基于范围 for 循环
- 布尔向量实现
- 在 Rcpp-Function 中使用布尔向量的子集(Rcpp 初学者的问题..)
- 无法将带有布尔网格的文本文件读取为向量的向量
- 计算 <Classtype*> 向量中所有项的布尔值的最有效方法,如果全部为真则返回 true
- 尼斯特布尔向量类
- 在C++中初始化布尔向量的标准方法是什么
- 在 O(N) 时间内使用布尔谓词函数对向量进行排序
- 为什么当我将真或假分配给布尔类型的向量时,下面的程序给我错误?
- 基于C 中布尔值向量中的向量中选择对象
- 向量中布尔值的均匀分布
- 如何将布尔向量转换为字符向量
- 为什么分离分配运算符| =不适用于布尔的向量
- 检查布尔(范围)的向量是否等于1和0的序列
- 是-!(condition)从布尔值(mask-boolean)中获得完整位向量的正确方法
- 将解码的 Base64 字节字符串转换为布尔向量
- C++ 基于成员布尔值对向量中的对象进行排序
- C++ 布尔向量错误:赋值时"iterator not dereferencable"
- placeNumbers应该返回数字的顺序,以便满足布尔值向量中编码的条件
- C++, (GLUT) - 在显示循环中维护布尔值的全局向量 - 使程序崩溃