最大长度的字符串类型

String type with max length

我需要实现一个 C++11 或 C++14 类型的字符串,它的行为就像 std:string,但有以下额外的 constraints/features:

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

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

我的第一直觉是使用包含 std::string 的模板 class 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 模板 class 没有公开 std::string 成员函数,我不想重新实现整个 std::basic_char 函数集,所以我认为我的方法从根本上是错误的。我怀疑以某种方式扩展 std::string 可能会更好,但使用标准库类型 "mess" 似乎有点可怕。

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

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

的 shorthand
std::basic_string<char, std::char_traits<char>, std::allocator<char>>

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

查看 this Q&A on advice on how to write a custom allocator. Howard Hinnant's website 中的示例,了解如何限制您需要复制的样板文件。

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