const char* 周围的轻量级容器不复制数据的长度

发布于 2024-09-10 14:10:28 字数 305 浏览 2 评论 0原文

我有一个传递 const char* 和长度的底层 API:

foo(const char* data, const uint32_t len);

我想将此数据/长度包装在一个轻量级容器中,该容器可以迭代并且能够随机访问但不能复制(例如像向量)。实现这一目标的最佳方法是什么? const char* 数据不一定是“字符串”;它可能始终包含 NULL。

我正在使用 STL 和 Boost。我见过 boost::as_array<>和 as_literal<> ——其中之一在这里合适吗?

I have a underlying API that passes a const char* and a length:

foo(const char* data, const uint32_t len);

I'd like to wrap this data/length in a light weight container that can be iterated and has the ability to be randomly accessed but not make a copy (e.g. like a vector). What is the best way to achieve this? The const char* data is not necessarily a 'string'; it may contain NULL's throughout.

I am using STL and Boost. I've seen boost::as_array<> and as_literal<> -- is one of these appropriate here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风尘浪孓 2024-09-17 14:10:28

开设这样的课程很容易。像这样的东西:

template <class T>
class array_ref {
public:
    // makes it work with iterator traits..
    typedef T         value_type;
    typedef size_t    size_type;
    typedef ptrdiff_t difference_type;

    typedef T*        pointer;
    typedef T*        iterator;
    typedef T&        reference;

    typedef const T*  const_pointer;
    typedef const T*  const_iterator;
    typedef const T&  const_reference;

public:
    array_ref(T *p, size_t n) : data_(p), len_(n) {}

    // iteration
    iterator begin()             { return data_; }
    iterator end()               { return data_ + len_; }
    const_iterator begin() const { return data_; }
    const_iterator end() const   { return data_ + len_; }

    // access
    reference operator[](size_t n)             { return data_[n]; }
    reference at(size_t n)                     { return data_[n]; }
    const_reference operator[](size_t n) const { return data_[n]; }
    const_reference at(size_t n) const         { return data_[n]; }

    // capacity
    size_t size() const { return len_; }
    bool empty() const  { return size() == 0; }

    // raw access
    T* data() const { return data_; }

    // etc...
private:
    T* data_;
    size_t len_;
};

这看起来像一堆代码,其中大部分并不是绝对必要的。然而,由于它是一个模板,编译器只会为所使用的方法生成代码。实际的类本身只使用指针和长度成员的空间。

但最终,这确实没有多大收获。由于指针本身就是很好的指针,因此我可能会在这里使用原始指针。

It would be easy to make such a class. Something like this:

template <class T>
class array_ref {
public:
    // makes it work with iterator traits..
    typedef T         value_type;
    typedef size_t    size_type;
    typedef ptrdiff_t difference_type;

    typedef T*        pointer;
    typedef T*        iterator;
    typedef T&        reference;

    typedef const T*  const_pointer;
    typedef const T*  const_iterator;
    typedef const T&  const_reference;

public:
    array_ref(T *p, size_t n) : data_(p), len_(n) {}

    // iteration
    iterator begin()             { return data_; }
    iterator end()               { return data_ + len_; }
    const_iterator begin() const { return data_; }
    const_iterator end() const   { return data_ + len_; }

    // access
    reference operator[](size_t n)             { return data_[n]; }
    reference at(size_t n)                     { return data_[n]; }
    const_reference operator[](size_t n) const { return data_[n]; }
    const_reference at(size_t n) const         { return data_[n]; }

    // capacity
    size_t size() const { return len_; }
    bool empty() const  { return size() == 0; }

    // raw access
    T* data() const { return data_; }

    // etc...
private:
    T* data_;
    size_t len_;
};

This looks like a bunch of code, most of it isn't strictly necessary. However, since it is a template the compiler will only generate code for the methods used. And the actual class itself only uses space for the pointer and the length members.

But in the end, this really isn't much of a gain. Since pointers themselves are nice pointers, I'd probably just use raw pointers here.

不必你懂 2024-09-17 14:10:28

我使用过 iterator_facade http://www.boost。 org/doc/libs/1_43_0/libs/iterator/doc/iterator_facade.html 与 iterator_range 一起,

您可以轻松地使用 iterator_range 来构建包装器, http://www.boost.org/doc/libs/1_42_0/libs/range/doc/utility_class.html# iter_range

boost::iterator_range<char*> range(begin, begin + N);

特殊情况可以用 iterator_facade 处理

I have used iterator_facade http://www.boost.org/doc/libs/1_43_0/libs/iterator/doc/iterator_facade.html together with iterator_range

you can easily use iterator_range to construct your wrapper, http://www.boost.org/doc/libs/1_42_0/libs/range/doc/utility_class.html#iter_range

boost::iterator_range<char*> range(begin, begin + N);

special cases can be handled with iterator_facade

温馨耳语 2024-09-17 14:10:28

我不认为 as_array 和/或 as_literal 会做你想要的。虽然写起来并不是非常困难,但我不知道现有的类是否可以做你想做的事(或者至少我认为你想做的事)。

编辑:我可能不应该说我不知道​​任何这样的类——我只是不知道任何特别众所周知、广泛使用或经过彻底测试的类。如果您搜索 12 到 15 年前左右的 comp.lang.c++ 和/或 comp.lang.c++.moderated 的档案,您可能会找到至少十几个(至少在 Google 新闻组搜索正常的情况下)眼下)。除非我记性特别差,否则我自己在某处发布了一个(虽然我现在似乎找不到它......)正如你可能从他们的年龄猜到的,但是,你可能不想使用大多数(有吗?)它们按原样使用——它们对 C++ 的使用通常相当原始。

I don't think as_array and/or as_literal will do what you want. While not terribly difficult to write, I don't know of an existing class intended to do what you you want (or at least what I think you want).

Edit: I probably shouldn't say I don't know of any such classes -- I just don't know of any that's particularly well known, widely used, or thoroughly tested. If you search the archives of comp.lang.c++ and/or comp.lang.c++.moderated from, say, 12 to 15 years ago or so, you can probably find at least a dozen (at least provided Google's newsgroup searching is working at the moment). Unless memory fails me particularly badly, I posted one myself somewhere along the line (though I can't seem to find it right now...) As you might guess from their age, however, you probably wouldn't want to use most (any?) of them as-is -- their use of C++ is often quite primitive.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文