c++ - 最大长度的字符串类型

标签 c++ string c++11 stdstring

我需要实现一个 C++11 或 C++14 类型的字符串,它的行为就像 std:string,但具有以下附加约束/功能:

  1. 声明期间指定的 WIDTH 参数。 STRING将 如果其长度大于 WIDTH 则抛出异常
  2. 在声明期间指定的可选 FIXED 参数。如果 STRING 的长度不等于 WIDTH,将抛出异常

在所有其他方面,STRING 应该表现得像 std::string 并公开与 std:string 相同的成员函数(例如 . append() 等..)。

我的第一直觉是使用包含 std::string 的模板类 STRING,如下所示:

template<int WIDTH= 0, bool FIXED = false>
class STRING {
    static_assert(WIDTH >= 0, "WIDTH of STRING cannot be negative.");
public:
    STRING() : value{} { }

    STRING(const std::string &s) { if (is_valid(s)) value = s; }

    STRING(const char c[]) { if (is_valid(c)) value = c; }

    STRING& operator=(const std::string& s){ if (is_valid(s)) value = s;}
    operator std::string() const { return value; }


    std::string value;

private:
    bool is_valid(const std::string &s) {
        if (WIDTH && s.length() > WIDTH)
            throw std::length_error{"STRING assignment failed. STRING too long."};
        if (FIXED && s.length() != WIDTH)
            throw std::length_error{"STRING assignment failed. STRING has wrong length."};
        return true;
    }
};

但是,上面的 STRING 模板类没有公开 std::string 成员函数,我不想重新实现整个 std::basic_char 函数集,所以我认为我的做法从根本上是错误的。我怀疑以某种方式扩展 std::string 可能会更好,但与标准库类型“混淆”似乎有点可怕。

我不确定这里最好的方法是什么,非常欢迎指向正确方向的指示。

最佳答案

完成此操作的最简单方法是修改分配器模板参数。请注意,std::string

的简写
std::basic_string<char, std::char_traits<char>, std::allocator<char>>

在分配器中,您可以放置​​检查溢出或长度的功能。

this Q&A关于如何编写自定义分配器的建议。 Howard Hinnant's website有一个关于如何限制您需要复制的样板文件的示例。

正如@rici 所说,大多数实现将使用短字符串优化 (SSO)。这意味着字符串类将有一个基于堆栈的小型存储(通常为 24 字节左右)的 union 和指向堆的三个指针。这意味着对于小字符串,提供的分配器可能会被完全忽略。这实际上意味着您不能将字符串限制为非常小(低于 SSO 阈值)。

关于c++ - 最大长度的字符串类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35023211/

相关文章:

c++ - 什么决定临时对象的生命周期何时扩展到 const 引用或右值引用?

c# - 从 C# 解决方案调试 C++ 解决方案

java - Android:如何将空的 EditText 字段排除在随机计数之外?

c++ - X 请求失败错误 : GLXBadFBConfig

java - 如何对 getString 单词进行空格?

java - 使用字符串标记器解析字符串两次

c++ - 我可以将智能指针与互斥锁成员一起使用吗?

c++ - 线程上的 Boost.Asio 并发问题

c++ - 如何用STL算法代替for循环?

c++ - Boost spirit lex 将 token 值写回输入流