引用不同大小的std::array,而不是基类中的std::array
Reference to std::array of different sizes instead of std::array in a base class
我有以下问题。考虑类
class face {
virtual std::vector<ptr>& get_vertices(void) const = 0;
};
class triangle : public face {
private:
std::vector<ptr> vertices;
public:
std::vector<ptr>& get_vertices(void) const { return vertices; };
};
class quadrilateral : public face {
private:
std::vector<ptr> vertices;
public:
std::vector<ptr>& get_vertices(void) const { return vertices; };
};
显然,三角形和四边形总是分别有3个和4个顶点。因此,我想通过适当大小的std::数组来交换std:向量,以节省std:矢量中三个额外指针所引起的开销。(这是因为我将拥有数百万个面……)现在,有没有机会像上面的std::vector一样,在std::array的面中拥有一个通用的访问函数?对于标准的C数组,我只需返回一个指向第一个数组条目及其大小的指针。有没有STL方法可以做同样或类似的事情?或者还有其他很好的方法来实现这个功能吗?
感谢您的阅读和可能的回答!!Andreas
不同大小的std::arrays
是不同的类型,所以我看不出有什么方法可以做你想做的。但是,如果您将begin()
和end()
常量迭代器返回到您内部持有的任何容器,或者返回一个包含两者的小范围对象,该怎么办?通过这种方式,可以将容器的大小与接口解耦,将其留给实现。
EDIT:为了澄清,为了隐藏数据存储表示(在本例中为std::array
的大小),您需要自己的face
迭代器类。这在指针方面很容易实现,因为对于每个face
专门化,您都知道底层数据结构的大小、开始和结束。但很明显,您不能在接口中直接使用std::array
的begin()
和end()
。
示例:
这是一个快速而肮脏的示例,说明了如何使用指针实现部分前向迭代器行为。我使用虚拟基类和OP中的一个实现作为起点。我还省略了所有的构造函数、赋值运算符等。它还假设了一个类Edge(可能是2D或3D点?)。
class face {
public:
typedef Edge* iterator;
typedef const Edge* const_iterator;
virtual iterator begin() = 0;
virtual const_iterator begin() const = 0;
virtual iterator end() = 0;
virtual const_iterator end() const = 0;
virtual size_t size() const = 0;
virtual ~face() {};
};
class triangle : public virtual face {
public :
virtual iterator begin() {return m_edges.begin();}
virtual const_iterator begin() const {return m_edges.begin();}
virtual iterator end() {return m_edges.end();}
virtual const_iterator end() const {return m_edges.end();}
virtual size_t size() const {return m_edges.size();}
private:
std::array<Edge, 3> m_edges;
};
std::array
在这里似乎不是一个解决方案,因为get_vertices
是一个纯虚拟函数,也就是说,您希望使用基类类型的指针(或引用)来访问它。如果你使用std::array
,你必须提供一个整数值作为std::array
类模板的第二个参数,这是可能的,如果你让face
成为一个类模板,类似这样:
template<size_t N>
class face {
virtual std::array<ptr, N>& get_vertices(void) const = 0;
};
class triangle : public face<3>{
//...
std::array<ptr, 3>& get_vertices(void) const { return vertices; };
};
class quadrilateral : public face<4> {
//...
std::array<ptr, 4>& get_vertices(void) const { return vertices; };
};
但这导致triangle
和quadrilateral
具有不同的基类:face<3>
和face<4>
是两个不同的类。这意味着,不能将triangle
和quadrilateral
混合在一起,例如在标准容器中,也不能使用相同基类类型的指针访问get_vertices
,因为现在没有单个基类。每个派生类都有自己的基类。
因此,解决方案是:
class triangle : public face {
private:
std::vector<ptr> vertices;
public:
triangle()
{
//it ensures that you've a vector of size 3, no more no less
vertices.reserve(3);
}
std::vector<ptr>& get_vertices(void) const { return vertices; };
};
类似地,您可以在quadrilateral
:中执行
quadrilateral()
{
//it ensures that you've a vector of size 4, no more no less
vertices.reserve(4);
}
现在,您的向量不会随意将自己调整为比实际需要的更大的大小,因为您已经通过调用reserve()
定义了容量,您将添加比其容量更多的项目。不会调整大小。
- C++11 中不同类型的对象的 std::array 的替代方案
- constexpr begin of a std::array
- C++如果必须在编译时确定大小,std::array 有什么意义?
- 标准::unordered_map 中的 std::array 的值初始化
- 确保编译时的特定 std::array 位置
- std::array的长度有大小限制吗?
- 将 std::array 移动到另一个 std::array
- 为什么 std::shared_ptr 被认为是"heavy"和"expensive",但 std::array "same perfprmance as plain (c-style) arrays
- std::bind on statd::array 的运算符 []
- 检查输入 std::array 指针数据是否等于某个常量数组
- 如何读/写或遍历 std::array 中的特定元素范围?
- 是否可以使用 std::array 作为 POD 结构的数据容器?
- 如何在C++中传递一个大小未知的 std::array?
- 在现代C++中将 std::array<std:::array<T,N>> 转换为 std::vector<T>
- 在 C++ 中访问 std::array<std::array> 元素
- 将标量+std::array+std::tuple转换为一个大元组
- 如何初始化 std::array<std::array<T, 2>, 2> 的对象?
- 初始化 std::p air<double, std::array<std::p air<double, double>, 3> >
- 单独移动数组(raw array, std::array, std::vector)的每个元素
- 包装方法返回 c++ std::array<std::string, 4> in cython