我需要实现类似于std:string
的C ++ 11或C ++ 14类型STRING,但具有以下附加约束/功能:
在所有其他方面,STRING应该表现得像std::string
,并且展示与std:string
相同的成员函数(例如.append()
等。)。
我的第一直觉是使用一个包含STRING
的模板类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;
}
};
但是,上面的STRING
模板类没有公开std::string
个成员函数,我不想重新实现整个std::basic_char
函数集,所以我认为我的方法基本上是错误。我怀疑某种程度上扩展std::string
可能会更好,但是对标准库类型的“混乱”似乎有点可怕。
我不确定这里最好的方法是什么,并且正确方向的指示将非常受欢迎。
答案 0 :(得分:5)
实现此目的的最简单方法是修改allocator模板参数。请注意,std::string
是
std::basic_string<char, std::char_traits<char>, std::allocator<char>>
在分配器内部,您可以设置功能以检查溢出或长度。
关于如何编写自定义分配器的建议,请查看this Q&A。 Howard Hinnant's website有一个关于如何限制需要复制的样板的示例。
正如@rici所说,大多数实现都将使用短字符串优化(SSO)。这意味着字符串类将具有union
基于堆栈的小存储(通常为24个字节左右)和三个指向堆的指针。这意味着对于小字符串,可能会完全忽略提供的分配器。这实际上意味着您无法将字符串限制为非常小(低于SSO阈值)。