【发布时间】:2025-11-27 21:00:01
【问题描述】:
我的容器需要存储一些关于其元素的信息。通常,我将其与元素分开存储。但是,我想通过将元素结构类型中的一个字段专用于外部使用,为用户提供节省内存的可能性。例如:
struct MyStuff
{
int foo;
char bar;
mutable char dedicated_for_external_use; // Because of alignment, this field
// won't increase sizeof (MyStuff)
};
这里的想法是,除了元素的容器之外,任何东西都不能访问该字段。由于容器存储一个副本(很像std::vector),因此如果您将任何给定值x 添加到多个容器中,这不会有问题。
如果可能的话,您将如何为此设计一个满足以下要求的界面?
- 应该是完全可选的。 IE。应该可以自动确定给定类型是否提供这样的字段,然后容器只会在可用时使用它。
- 理想情况下,不依赖于类型特征等,因为我需要最大的编译器兼容性。
- 应该易于使用。 IE。如果您可以并且想要为
MyStuff类型启用此优化,您可以使用 3 行代码而不是 25 行代码来实现。另一方面,内部复杂性并不重要。 - 最好完全排除误报。我的意思是:如果您检查字段
foo_bar,则存在这种字段的可能性很小,原因完全不相关(我认为鸭式打字根本不适用于C++)。更好的方法是检查类型是否从我的库中继承标记类ProvidesExternalUseField,因为这不是偶然的。
编辑
我知道 Boost.Intrusive,但我想要的是不同的东西。如果我这样做并创建一个带有单个 char 字段的钩子类,则在许多情况下它不能用于节省内存。如果继承类型有一个int 作为第一个字段,char 字段将被填充为 4 个字节。 IE。你通常需要复杂的类型内部知识才能“挤压”这样的外部使用字段,但继承并没有真正提供它:
struct hooks { mutable char dedicated_for_external_use; };
struct MyStuff : hooks
{
int foo;
char bar;
};
这里,MyStuff 的大小将是 12 个字节,而不是 8 个。
【问题讨论】:
-
也许 Boost.Intrusive (boost.org/doc/libs/1_43_0/doc/html/intrusive.html) 和
boost::intrusive_ptr(boost.org/doc/libs/1_43_0/libs/smart_ptr/intrusive_ptr.html) 可能会给一些启发。 -
当您说“最大编译器兼容性”时,这在实践中意味着什么?您需要使用它的编译器有多糟糕?
-
@jalf:嗯,最好它应该在兼容 C++98 的编译器上工作。我只是说如果可能的话,我宁愿不使用任何非标准扩展或 C++0x 的东西。
-
@Philipp:谢谢,我知道 Boost.Intrusive,但我想要的有点不同。我会更好地更新问题。
-
那么类型特征使用起来非常安全。它们仅依赖于 C++98 特性。所以定义一个像
has_extra_field<T>这样的特征
标签: c++ interface-design