所以我尝试用 C++ 创建一个“Table”类,其结构如下:
表.h
class Table
{
private:
class TableImpl;
TableImpl* impl;
};
表.cpp
class Table::TableImpl
{
private:
class Row
{
private:
template <typename T>
class RowDataCell
{
T data;
}
std::vector<RowDataCell*> data;
};
std::vector<Row*> rows;
};
TableImpl
由 Row
对象的 std::vector
组成,每个 Row
对象由通用 RowDataCell
对象的 std::vector
。唯一的问题是,我无法创建 std::vector
因为我需要为 RowDataCell*
提供模板参数,这将阻碍我拥有一个容器的目标杂项对象。
有没有办法使用标准 C++ 来实现这个目标。
最佳答案
有两种合理的方法。
第一个是区分 union ,另一个是旧 C 风格的类型安全变体 void*
“任何东西都可能在这里”。
我首先提两个boost
它们的实现:
boost::variant<A,B,C>
(以及传入的 std::experimental::variant
)是一个歧视联盟。它可以存储 A
类型的一件东西, B
或C
。有多种类型安全的方法可以获取元素,或者通过“访问”对它们执行操作。 Variant 对于它可以保存的类型有一些限制,更多的限制取决于您注入(inject)这些类型的方式。
boost::any
(以及传入的 std::experimental::any
)是类型安全的 void*
具有值语义。几乎任何东西都可以存储在其中(any
要求您的对象是可复制构造的),但只有当您知道其中存储的事物的确切类型并询问它时,您才能访问它。
自己编写其中任何一个都是可行的,但我建议使用它们,或者至少理解它们并克隆它们的界面和模式的很大一部分。
variant
可以在其自身“内部”存储实例,这通常是更好的方法。您可以使用 union
来模拟它、类型列表、该列表的索引,以及一堆元编程样板。顺便说一句,对齐问题很棘手。
any
写起来比较容易,但仍然有一点挑战。它是一个非常基本的类型删除对象,仅具有“转换为 X 类型”(通过 typeid
或等效方法)并公开拷贝。如果你见过std::function
实现,你就成功了一半。
关于c++ - 各种类型的容器 - C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28179376/