可以利用 std::basic_string 来实现具有长度限制的字符串吗?
我正在使用一个低级 API,它接受 char* 和数值来分别表示字符串及其长度。我的代码使用 std::basic_string
并通过适当的转换调用这些方法。不幸的是,其中许多方法接受不同大小的字符串长度(即 max(unsigned char
)、max(short
) 等...),而我一直在写代码以确保我的字符串实例不超过低级 API 规定的最大长度。
默认情况下,std::basic_string
实例的最大长度受 size_t
的最大值(max(unsigned int
) 或最大(__int64
))。有没有办法操纵 std::basic_string 实现的特征和分配器实现,以便我可以指定自己的类型来代替 size_t ?通过这样做,我希望利用 std::basic_string
实现中的任何现有边界检查,这样我在执行翻译时就不必这样做。
我的初步调查表明,如果不编写自己的字符串类,这是不可能的,但我希望我忽略了一些东西:)
I'm working with a low-level API that accepts a char*
and numeric value to represent a string and its length, respectively. My code uses std::basic_string
and calls into these methods with the appropriate translation. Unfortunately, many of these methods accept string lengths of varying size (i.e. max(unsigned char
), max(short
), etc...) and I'm stuck writing code to make sure that my string instances do not exceed the maximum length prescribed by the low-level API.
By default, the maximum length of an std::basic_string
instance is bound by the maximum value of size_t
(either max(unsigned int
) or max(__int64
)). Is there a way to manipulate the traits and allocator implementations of a std::basic_string
implementation so that I may specify my own type to use in place of size_t
? By doing so, I am hoping to leverage any existing bounds checks within the std::basic_string
implementation so I don't have to do so when performing the translation.
My initial investigation suggests that this is not possible without writing my own string class, but I'm hoping that I overlooked something :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以将自定义分配器传递给
std::basic_string
,它的最大大小为您想要的任何值。这应该足够了。也许是这样的:那么你可以这样做:
编辑:我刚刚做了一个测试,以确保它按预期工作。下面的代码对其进行测试。
最后一个
s += s
会将其放在顶部并导致std::bad_alloc
异常(因为我的限制仅低于 64k)。不幸的是,gcc 的 std::basic_string::max_size() 实现并不将其结果基于您使用的分配器,因此它仍然声称能够分配更多。 (我不确定这是否是一个错误......)。但这肯定会让您以简单的方式对字符串的大小施加硬性限制。您甚至可以将最大大小设置为模板参数,这样您只需为分配器编写一次代码。
you can pass a custom allocator to
std::basic_string
which has a max size of whatever you want. This should be sufficient. Perhaps something like this:Then you can probably do this:
EDIT: I've just done a test to make sure this works as expected. The following code tests it.
That last
s += s
will put it over the top and cause astd::bad_alloc
exception, (since my limit is just short of 64k). Unfortunately gcc'sstd::basic_string::max_size()
implementation does not base its result on the allocator you use, so it will still claim to be able to allocate more. (I'm not sure if this is a bug or not...).But this will definitely allow you impose hard limits on the sizes of strings in a simple way. You could even make the max size a template parameter so you only have to write the code for the allocator once.
我同意 Evan Teran 的解决方案。这只是他的解决方案的修改:
请注意,您根本不应该在
myalloc
中使用多态性。所以这是灾难性的:你只需使用它就好像它是一个单独的类型一样,在以下情况下它是安全的:
I agree with Evan Teran about his solution. This is just a modification of his solution no more:
Be aware you should not use polymorphism at all with
myalloc
. So this is disastrous:You just use it as if it is a separate type, it is safe in following case:
你不能创建一个以 std::string 作为父类并覆盖 c_str() 的类吗?
或者定义您自己的 c_str16()、c_str32() 等并在那里实现翻译?
Can't you create a class with std::string as parent and override c_str()?
Or define your own c_str16(), c_str32(), etc and implement translation there?