具有最大长度的字符串类型

Arn*_*amm 4 c++ string stdstring c++11

我需要实现一个类似于C++ 11或C++ 14类型的STRING std:string,但具有以下附加约束/功能:

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

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

我的第一直觉是使用一个STRING包含a 的模板类std::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;
    }
};
Run Code Online (Sandbox Code Playgroud)

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

我不确定这里最好的方法是什么,并且正确方向的指示将非常受欢迎.

Tem*_*Rex 5

完成此操作的最简单方法是修改allocator模板参数.请注意,这std::string是一个简写

std::basic_string<char, std::char_traits<char>, std::allocator<char>>
Run Code Online (Sandbox Code Playgroud)

在分配器内部,您可以设置功能以检查溢出或长度.

关于如何编写自定义分配器的建议,请参阅此问答.Howard Hinnant的网站上有一个关于如何限制复制需要的样板的例子.

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

  • 短字符串优化意味着可能没有分配. (2认同)