编写不区分大小写的字符串类

Posted

技术标签:

【中文标题】编写不区分大小写的字符串类【英文标题】:writing a case insenstive string class 【发布时间】:2014-08-19 15:40:04 【问题描述】:

我正在阅读 Herb Sutter 的书Exceptional C++,在第二项中您需要编写一个不区分大小写的字符串类 ci_string,其行为如下:

#include <assert.h>

ci_string s("AbCdE");

// case insensitive
//
assert(s == "abcde");
assert(s == "ABCDE");
// still case-preserving, of course
//
assert(strcmp(s.c_str(), "AbCdE") == 0);
assert(strcmp(s.c_str(), "abcde") != 0);

我的想法是让这个类与std::string 相同,并且只覆盖operator==

#include <string>
#include <cctype>

using namespace std;

struct ci_string : string 

    bool operator==(const ci_string& lhs) 
        if (this->length() != lhs.length())
            return false;
        for (size_type i = 0; i != this->length(); ++i) 
            if (tolower((*this)[i]) != tolower(lhs[i]))
                return false;
        
        return true;
    
;

但是,如果将它与第一个代码结合使用,则此代码不会编译,因为没有合适的 ci_string 构造函数用于 const char[] 作为“AbCdE”,尽管父类有一个。

解决这个问题的最优雅的方法是什么?我希望代码尽可能短,不需要重写字符串的构造函数和成员函数,如c_str() 等。

【问题讨论】:

您可以使用 basic_stringchar_traits 进行不敏感比较。 你看过书中的实际解决方案了吗?或阅读here 我还没有查看解决方案。 继承不应该像struct ci_string : public string 吗?除此之外,继承可能是完全错误的方法。 @πάνταῥεῖ 不,除非你想变得冗长。如果有的话,最好说struct ci_string : private std::string,因为在这种情况下,公共继承不是一个好主意。 【参考方案1】:

解决问题的更优雅的方法是使用char_traits,如答案所示。

但为了避免使用您的方法的样板代码,您可以在子类中使用using string::string;“复制”父构造函数。

【讨论】:

如果我尝试将using string::string; 放在子类中,我得到的是:error C2039: 'string' : is not a member of 'std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt;' 嗯,它确实适用于我的编译器。也许尝试使用 std::string 是 typedef 的实际类型:using basic_string&lt;char&gt;::basic_string; 现在是error C2886: 'basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt;&gt;' : symbol cannot be used in a member using-declaration 这个特性是在 c++11 中引入的。您的编译器似乎还不支持它。您必须为std::string 的每个构造函数定义一个构造函数并将它们委托给父级。 我不确定我是否理解。如果您定义了一个不区分大小写的字符特征(可能是从std::char_traits&lt;char&gt; 派生并覆盖了需要更改的少数函数),则没有需要复制的构造函数;你还在使用std::basic_string。 (另一方面,您需要实现&lt;&lt;&gt;&gt; 运算符和getline;标准版本要求流和字符串使用相同的char_traits。)

以上是关于编写不区分大小写的字符串类的主要内容,如果未能解决你的问题,请参考以下文章

编写不区分大小写的Cypher查询以匹配Neo4j中字符串的开头

Django模板中的Django不区分大小写字符串比较

Cloud Firestore 查询是不是仍区分大小写?

编写程序,判断一个字母在字母表中的位置(不区分大小写)。例如输入A,输出1,输入Z,输出26?

matlab 的 M 文件的命名区不区分大小写的

jquery .append()区分大小写的元素