【发布时间】:2021-04-11 18:12:28
【问题描述】:
我正在尝试摆脱 void* + size 在同一容器中存储任意数组类型的方法。
目前看起来有点像这样:
#include <iostream>
#include <map>
#include <string>
#include <cstddef>
struct fat_pointer {
void *data;
size_t size;
size_t count;
fat_pointer() : data(nullptr), size(0), count(0)
{
}
fat_pointer(void *data_, size_t size_, size_t count_) :
data(data_), size(size_), count(count_)
{
}
bool valid() const {
return data != nullptr;
}
template <typename T>
const T as() {
return static_cast<T>(data);
}
};
int main(int argc, char* argv[])
{
// data can be anything, these two are just for example
const double v1[] = {1.1, 2.2, 3.3, 4.4, 5.5};
const int v2[] = {1, 2, 3, 4, 5};
std::map<std::string, fat_pointer> data;
data.insert(std::pair<std::string, fat_pointer>("V1", fat_pointer((void*)v1, sizeof(v1[0]), sizeof(v1) / sizeof(v1[0]))));
data.insert(std::pair<std::string, fat_pointer>("V2", fat_pointer((void*)v2, sizeof(v2[0]), sizeof(v2) / sizeof(v2[0]))));
auto values = data["V1"];
if (values.valid()) {
std::cout << values.as<double*>()[2] << std::endl;
}
return 0;
}
这种方法非常容易出错,不提供任何类型的验证,不允许对元素轻松计数或应用算法,所以我真的想摆脱它。
有没有办法告诉编译器该值将是一个任意类型的数组?或者有没有其他方法可以避免fat_pointer hack?
【问题讨论】:
-
也许你正在寻找类似
std::any的东西。 -
根据
std::any的描述,我将不得不创建类似std::vector<std::any>的东西,这绝对不是一个选项,因为它会使处理这些数据变得非常困难 -
std::any可以保存一个(智能)指针,并且可以检查您的fat_pointer是否丢失。 -
我正在使用来自 3rd 方库的数组,它们不应该是我的代码中的
delete[]。最重要的是std::any不会做,因为我在很多地方检查count。我想使用std::any_of之类的东西,但是那里的类型太多+其他代码可能需要添加更多:( -
如果你想要像
std::map这样的容器来保存多个不同类型的数组,那么如果你不想使用std::any或std::variant作为数组元素类型,你基本上会被困住使用void*。容器元素必须是相同的类型,就像数组元素一样。
标签: c++ types casting type-conversion