是否可以使用std :: basic_string来实现具有长度限制的字符串? [英] Can one leverage std::basic_string to implement a string having a length limitation?

查看:411
本文介绍了是否可以使用std :: basic_string来实现具有长度限制的字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个低级API接受 char * 和数字值来分别表示一个字符串及其长度。我的代码使用 std :: basic_string 并调用这些方法与适当的翻译。不幸的是,许多这些方法接受不同大小的字符串长度(即max( unsigned char ),max( short ) ,etc ...),我坚持写代码,以确保我的字符串实例不超过低级API规定的最大长度。

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.

通过默认情况下, std :: basic_string 实例的最大长度由 size_t unsigned int )或max( __ int64 ))。是否有一种方法来操纵 std :: basic_string 实现的traits和allocator实现,以便我可以指定我自己的类型来代替 size_t ?通过这样做,我希望利用 std :: basic_string 实现中的任何现有的边界检查,所以我在执行翻译时不必这样做。

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 :)

推荐答案

,您可以将自定义分配器传递到 std :: basic_string ,其最大大小为任何您想要的。这应该足够了。可能是这样的:

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:

template <class T>
class my_allocator {
public:
    typedef T              value_type;

    typedef std::size_t    size_type;
    typedef std::ptrdiff_t difference_type;
    typedef T*             pointer;
    typedef const T*       const_pointer;
    typedef T&             reference;
    typedef const T&       const_reference;

    pointer address(reference r) const             { return &r; }
    const_pointer address(const_reference r) const { return &r; }

    my_allocator() throw() {}

    template <class U>
    my_allocator(const my_allocator<U>&) throw() {}

    ~my_allocator() throw() {}

    pointer allocate(size_type n, void * = 0) {
        // fail if we try to allocate too much
        if((n * sizeof(T))> max_size()) { throw std::bad_alloc(); }
        return static_cast<T *>(::operator new(n * sizeof(T)));
    }

    void deallocate(pointer p, size_type) {
        return ::operator delete(p);
    }

    void construct(pointer p, const T& val) { new(p) T(val); }
    void destroy(pointer p)                 { p->~T(); }

    // max out at about 64k
    size_type max_size() const throw() { return 0xffff; }

    template <class U>
    struct rebind { typedef my_allocator<U> other; };

    template <class U>
    my_allocator& operator=(const my_allocator<U> &rhs) {
        (void)rhs;
        return *this;
    }
};

那么你可以这样做:

typedef std::basic_string<char, std::char_traits<char>, my_allocator<char> > limited_string;

编辑:我刚做了测试,如预期。以下代码测试它。

I've just done a test to make sure this works as expected. The following code tests it.

int main() {
    limited_string s;
    s = "AAAA";
    s += s;
    s += s;
    s += s;
    s += s;
    s += s;
    s += s;
    s += s; // 512 chars...
    s += s;
    s += s;
    s += s;
    s += s;
    s += s;
    s += s; // 32768 chars...
    s += s; // this will throw std::bad_alloc

    std::cout << s.max_size() << std::endl;
    std::cout << s.size() << std::endl;
}

最后 s + = s 会把它放在顶部,并导致 std :: bad_alloc 异常,(因为我的极限只是短于64k)。不幸的是,gcc的 std :: basic_string :: max_size()实现不会将其结果基于您使用的分配器,因此它仍然声称能够分配更多。 (我不知道这是否是一个bug或者...)。

That last s += s will put it over the top and cause a std::bad_alloc exception, (since my limit is just short of 64k). Unfortunately gcc's std::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...).

但是这将允许你对一个简单的字符串的大小强加硬限制办法。您甚至可以将max size作为模板参数,因此您只需为分配器编写一次代码。

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.

这篇关于是否可以使用std :: basic_string来实现具有长度限制的字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆