【问题标题】:How to write constructor/assignment operator overloads for custom string types?如何为自定义字符串类型编写构造函数/赋值运算符重载?
【发布时间】:2016-07-19 17:29:08
【问题描述】:
struct ci_char_traits : public std::char_traits<char>
{
  static bool eq( char c1, char c2 ) { return toupper( c1 ) == toupper( c2 ); }
  static bool ne( char c1, char c2 ) { return toupper( c1 ) != toupper( c2 ); }
  static bool lt( char c1, char c2 ) { return toupper( c1 ) <  toupper( c2 ); }

  static int compare( const char* s1, const char* s2, size_t n );
  static const char* find( const char* s, int n, char a );
};

using ci_string = std::basic_string<char, ci_char_traits>;

我正在使用这个 char_traits 导数,它应该可以帮助我处理不区分大小写的字符串比较。从字符文字构造 ci_strings 时它工作得非常好,但是我经常遇到我有一个或两个 std::strings 并希望不区分大小写地比较它们的情况。 有没有办法编写自定义构造函数或赋值/转换运算符以从 std::string 转换为 ci_string 或者除了迭代 std::strings 并在每个字符上调用 tolower 之外没有其他可能性?

【问题讨论】:

    标签: c++ string c++11


    【解决方案1】:

    要从std::string 构造ci_string,您可以使用采用迭代器范围的构造函数。这将遍历std::string并将其字符的副本存储到ci_string

    std::string foo = "test";
    ci_string bar(foo.begin(), foo.end());
    

    这适用于任何basic_string 特化,只要基础类型(在本例中为char)相同。您不会希望使用std::wstring 执行此操作,因为它使用wchar_t,这会给您带来不正确的转换。

    此外,正如 cmets 中所指出的,您还可以使用带有 const char* 和计数的构造函数来构造 ci_string

    std::string foo = "test";
    ci_string bar(foo.c_str(), foo.length());
    

    这样做的好处是您不能使用任何“字符串”,它在后台使用 char 以外的其他内容,例如 std::wstring

    【讨论】:

    • 另外,您可以使用将char* 和长度作为输入的构造函数:ci_string bar(foo.c_str(), foo.size()); 这也将阻止尝试从std::wstring 构造ci_string,因为@987654339 @ 不能分配给 char*
    • @RemyLebeau 好点。我们甚至不需要大小,因为它只有一个 const char* 的构造函数
    • 是的,但是该构造函数必须手动计算 char 元素。由于源字符串已经知道有多少存在,最好在知道时将该值传递给构造函数。
    • @RemyLebeau 我总是对那个犹豫不决,因为我不记得大小是否需要空终止大小。只需使用指针就可以让我不必担心。
    • 空终止符从不计算在内,不在构造函数中,不在size()length() 中。如果字符串包含 embedded 空值,则那些 会被计算在内,因为它们是字符数据。在这种情况下,您必须使用将计数作为输入的构造函数,否则它们将被视为空终止符并且不会被正确复制。
    猜你喜欢
    • 2014-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-26
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 2013-10-23
    相关资源
    最近更新 更多