我正在寻找关于如何组织和访问我的数据的更好的解决方案。
我的数据是一组结构(在下面的示例中为 _array_10
和 _array_20
),其中包含 std::array
不同尺寸(见下文my_data
)。
理想情况下,我想访问它,因为它是具有不同长度的结构数组,但这是不允许的,因为不同的长度是不同的类型。
我在下面的解决方案有效,但我发现它非常难看(特别是 void *
的数组)。
Q1。关于如何拥有更安全、更高效/便携或至少不那么丑陋的解决方案的任何想法?
Q2。没有模板的建议解决方案是否可移植?它依赖于长度存储在其余数据之前的事实,因为将指针转换为长度错误的对象会弄乱对可变长度第一个字段之后的所有字段的访问。
我的限制包括:
std::vector
my_data
的数组最大可能长度 _array_10
, _array_20
等)将被放置在专门为其保留的内存区域中 使用 data_view 和 template 需要在构建时了解数组的长度。如果我们能避免它,那就太好了。
#include <iostream>
#include <array>
std::array<void *, 2> _ptrs;
template <int length>
struct my_data
{
int array_length;
std::array<int, length> something;
std::array<int, length> data;
my_data()
{
array_length = length;
}
};
struct my_data_view
{
int array_length;
const int * something;
const int * data;
template <int length>
my_data_view(my_data<length> const & data_in) :
array_length(length),
something(data_in.something.data()),
data(data_in.data.data())
{}
};
template <int length>
void
print_element(int array_idx, int element)
{
my_data<length> * ptr = reinterpret_cast<my_data<length> *>(_ptrs[array_idx]);
std::cout << "array " << length << ", data[" << element << "] = " << ptr->data[element] << ".\n";
}
void
print_element(int array_idx, int element)
{
my_data<1> * ptr = reinterpret_cast<my_data<1> *>(_ptrs[array_idx]);
int length = ptr->array_length;
int data_to_print = 0;
switch (length)
{
case 10:
{
data_to_print = reinterpret_cast<my_data<10> *>(_ptrs[array_idx])->data[element];
break;
}
case 20:
{
data_to_print = reinterpret_cast<my_data<20> *>(_ptrs[array_idx])->data[element];
break;
}
}
std::cout << "array " << length << ", data[" << element << "] = " << data_to_print << ".\n";
}
void
print_element(my_data_view view, int element)
{
int length = view.array_length;
int data_to_print = view.data[element];
std::cout << "array " << length << ", data[" << element << "] = " << data_to_print << ".\n";
}
int
main()
{
my_data<10> _array_10;
my_data<20> _array_20;
_ptrs[0] = static_cast<void *>(&_array_10);
_ptrs[1] = static_cast<void *>(&_array_20);
_array_10.data[5] = 11;
_array_20.data[5] = 22;
std::cout << "using template\n";
print_element<10>(0, 5);
print_element<20>(1, 5);
std::cout << "\nwithout template\n";
print_element(0, 5);
print_element(1, 5);
std::cout << "\nusing data_view\n";
print_element(my_data_view(_array_10), 5);
print_element(my_data_view(_array_20), 5);
}
最佳答案
您可以创建一个不分配的动态 View 类:
struct my_data_view
{
int array_length;
std::span<int> something;
std::span<int> data;
template<int length>
my_data_view(my_data<length> const& data) :
array_length{length}, something{data.something}, data{data.data}
{}
};
跨度只是一个指针和一个大小。如果您无权访问
std::span
(来自 C++20)您可以简单地将这些成员替换为 int*
并使用 array_length
为大小。这个
my_data_view
类型是这样使用的:void
print_element(my_data_view view, int element)
{
int length = view.array_length;
int data_to_print = view.data[element];
std::cout << "array " << length << ", data[" << element << "] = " << data_to_print << ".\n";
}
这是与
std::span
一起使用的代码和简单的int*
.
关于c++ - C++11 中不同类型对象的 std::array 替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60263522/