数组模板兼容性的良好模式是什么?
我想创建具有可变长度元素数组的对象,并让它们在基类/派生类意义上兼容。在 C 中,可以将一个不确定的数组放在 struct 的末尾,然后只需 malloc 对象来包含完整的数组:
struct foo {
int n;
double x[];
} ;
struct foo *foo1 = (foo *)malloc( sizeof( foo ) + sizeof( double[4] ) );
struct foo *foo2 = (foo *)malloc( sizeof( foo ) + sizeof( double[100] ) );
在 C++ 中,看起来你可以这样做:
template <unsigned I>
class foo {
public:
int n;
double x[I];
} ;
但是:
auto foo1 = new foo<4>( );
auto foo2 = new foo<100>( );
if (foo1 == foo2) cerr << "incompatible pointers";
你可以这样做有一个共同的基类,但这有必要吗?我只想使用 foo1 和 foo2,其中每个对象都知道其数组的长度。
我的应用程序适用于运行 FreeRTOS 的 ESP32 微控制器。它具有有限的非虚拟 RAM 和稍微复杂的分配系统,因为各种内存块的功能不同(有些较慢,有些不能包含可执行代码,有些不能通过 DMA 访问等),因此分配对象的各个部分的多个块(例如,通过使用 std::vector
作为末尾的 double
数组)变得复杂。
我在对象构造时知道 double 数组的长度,但我希望标头和数组位于单个分配的内存块中(这样它就可以具有我需要的特征)稍后有)。
C 风格的方法很好,但最好有 C++ 功能,例如数组迭代(对于各种对象,每个对象都有不同数量的 double )。另外,本机 C++ 解决方案允许我在 x[]
数组中包含对象,而不是在原始分配的内存中放置 new
。因此,例如:(
auto a[] = { new foo<5>( ), new foo<10>( ), new foo<15>( ) };
for (auto i : a)
for (auto j : i.x)
cout << log10( j ); // prints 40 logs of doubles
我预计这会出现 C++ 语法错误,但希望它传达了这个想法。如果我可以将所有 foo 放入一个公共容器中,我就可以找出语法。 )
I would like to create objects having a variable-length array of elements, and have them be compatible in a base/derived-class sense. In C, one could put an indeterminate array at the end of a struct
and then just malloc the object to contain the full array:
struct foo {
int n;
double x[];
} ;
struct foo *foo1 = (foo *)malloc( sizeof( foo ) + sizeof( double[4] ) );
struct foo *foo2 = (foo *)malloc( sizeof( foo ) + sizeof( double[100] ) );
In c++, it seems like you could do:
template <unsigned I>
class foo {
public:
int n;
double x[I];
} ;
but:
auto foo1 = new foo<4>( );
auto foo2 = new foo<100>( );
if (foo1 == foo2) cerr << "incompatible pointers";
You can do it with a common base class, but is that necessary? I just want to use foo1
and foo2
, where each object knows the length of its array.
My application is for an ESP32 microcontroller running FreeRTOS. It has limited, non-virtual RAM and a slightly complicated allocation system because of differing capabilities of various chunks of memory (some is slower, some can't contain executable code, some can't be accessed by DMA, etc.) So allocating multiple chunks for pieces of an object (for example, by using std::vector
for the array of double
at the end) becomes complicated.
I know the length of the double
array at object construction time, but I would like the header and the array to be in a single allocated block of memory (so it can have the characteristics I need for it to have later).
The C-style way of doing it would be fine, but it would be nice to have C++ features like iteration over the array (for various objects, which will each have different numbers of double
s). Plus, a native C++ solution would allow me to have objects in the x[]
array, instead of fooling around with placement new
in raw allocated memory. So, for example:
auto a[] = { new foo<5>( ), new foo<10>( ), new foo<15>( ) };
for (auto i : a)
for (auto j : i.x)
cout << log10( j ); // prints 40 logs of doubles
(I expect that's got C++ syntax errors, but hopefully it communicates the idea. I can figure out the syntax for that, if I could get all the foo
s into a common container.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
作为一名低级 C++ 开发人员,我完全理解您的需求,但遗憾的是,无论有或没有模板,标准 C++ 中的灵活数组成员都无法替代。您必须通过编译器扩展继续使用灵活的数组成员。
它们没有包含在语言中,因为以目前的形式,它们本质上是一种 hack。他们在继承或组合方面表现不佳。
模板的问题在于,灵活数组版本具有所有大小的通用类型的数组。这意味着您可以将它们放在数组中,让非模板函数将它们作为参数等:
在模板版本中,类型
foo<1>
和foo<2>
是完全不相关,因此您不能将它们放入数组中或使用非模板函数来获取它们:std::array
在本讨论中无济于事,并且从一个数组继承仍然存在以下问题:不相关的类型。然而,由于这仍然是 C++(尽管是非标准的),所以您至少可以有一些额外的细节:
As a low-level C++ developer, I understand exactly what you need, and sadly, there is no replacement for flexible array members in standard C++, with or without templates. You have to keep using flexible array members via compiler extensions.
They are not included in the language since in their current form, they are essentially a hack. They don't do well with inheritance or composition.
The problem with templates is that, the flexible array version has a common type of arrays of all sizes. That means you can place them in arrays, have non-template functions take them as parameters etc:
With the template version, types
foo<1>
andfoo<2>
are completely unrelated, so you cannot put them in arrays or have non-template functions that take them:std::array
won't help in this discussion, and inheriting from one will still have the problem of having unrelated types.However, since this is still C++ (albeit non-standard), you can at least have some additional niceties: