【问题标题】:C++ - get const access to sub string of a stringC++ - 获取对字符串的子字符串的 const 访问权限
【发布时间】:2014-05-21 08:43:44
【问题描述】:

假设我有一个Storage 类:

class Storage
{
public:

  const string& get()                     const { return m_data;      }
  const char&   get(int ind)              const { return m_data[ind]; }
  const string& get(int s_ind, int e_ind) const { /* TBD */           }

private:
  string m_data; ///< Data is so big that part of it is stored on disk
}

假设我有一个 Writer 类,它获取 const Storage&amp; 并需要访问其数据。
我的问题,有没有办法实现:

const string& get(int s_ind, int e_ind) const;

即,仅对 string 的一部分进行 const 访问。

注意事项:

get() 被无数次调用,它是我的应用程序的瓶颈。我想避免在访问数据时分配新对象。

【问题讨论】:

  • 返回对内部类成员的引用通常是一种不好的方法
  • 拿到后在外面怎么用?你不能在不创建字符串的情况下返回一个字符串,但你可以返回例如一对迭代器
  • 在我的脑海中,唯一的方法可能是拥有另一个 std::string 成员变量,您将在其中存储 sub-string 然后返回它。编译器通常会优化分配以最小化临时对象的创建。
  • 提出了一个string views 提案,它可能或多或少地满足了您的需求。不要认为它达到了标准(还没有?)。不过,Boost 可能也有类似的东西。

标签: c++ string substring constants


【解决方案1】:

有没有办法实现:

const string& get(int s_ind, int e_ind) const;

即,仅对字符串的一部分进行 const 访问。

绝对不是。

通常会做的——并且可能会解决你的瓶颈——是创建一个类来存储 const char*size_t(或者同样是 beginend const char*s,或迭代器,但没有理由限制将其用于std::strings 中的数据)。

然后您可以创建一个“引用”string 内的文本的对象,并使用它直到发生任何会使迭代器无效或对这些字符的引用的事件发生 - 请参阅标准或例如cppreference。可以支持stream 输出、比较、索引等。从std::string 托管数据驱动。

显然,您无法将这样的类传递给硬编码 std::string 类型的函数,但您可以将其编写为具有类似的接口,这样可以减轻痛苦。

只是作为一个品尝者(还没有看到编译器/根据需要充实)......

class Text_Ref
{
  public:
    Text_Ref(const char* p, size_t n) : p_(p), n_(n) { }

    // intuitive values for &text_ref[x] BUT text_ref[n] may not be nul
    const char& operator[](size_t o) const { return p_[n]; }

    *** OR ***

    // text_ref[n] is nul BUT can't use &text_ref[x]
    char operator[](size_t o) const { return o == n ? '\0' : p_[n]; }

    // same design trade off as the operator[] alternatives above
    char at(size_t o) const
    {
       if (o > n) throw std::out_of_range();
       return o == n ? '\0' : p_[n];
    }

    bool empty() const { return n == 0; }

    size_t size() const { return n; }
    size_t length() const { return n; }

    int compare(const char* p) const
    {
        do
        {
            if (*p != *p_)
                return (int)*p_ - *p;
        } while (*p);

        return 0;
    }

    bool operator< (const char* p) const { return compare(p) <  0; }
    bool operator<=(const char* p) const { return compare(p) <= 0; }
    bool operator==(const char* p) const { return compare(p) == 0; }
    bool operator!=(const char* p) const { return compare(p) != 0; }
    bool operator>=(const char* p) const { return compare(p) >= 0; }
    bool operator> (const char* p) const { return compare(p) >  0; }

  private:
    const char* p_;
    size_t n;
};

inline std::ostream& operator<<(std::ostream& os, const Text_Ref& t)
{
    return os.write(t.data(), t.size());
}

【讨论】:

    猜你喜欢
    • 2011-12-27
    • 2014-12-13
    • 2011-05-25
    • 2015-07-07
    • 1970-01-01
    • 2012-01-26
    • 2018-07-12
    相关资源
    最近更新 更多