Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ STL性格特征的意义是什么?_C++_String_Stl_Stdstring_Char Traits - Fatal编程技术网

C++ STL性格特征的意义是什么?

C++ STL性格特征的意义是什么?,c++,string,stl,stdstring,char-traits,C++,String,Stl,Stdstring,Char Traits,我注意到在我的SGI STL参考资料副本中,有一个关于性格特征的页面,但我看不出这些特征是如何使用的?它们是否替换string.h函数?它们似乎没有被std::string使用,例如std::string上的length()方法没有使用字符特征length()方法。为什么字符特征存在并且在实践中使用过?字符特征是流和字符串库的一个极其重要的组成部分,因为它们允许流/字符串类将存储的字符逻辑与应该对这些字符执行的操作逻辑分开人物 首先,C++中的默认字符特征类“代码>字符特征”被广泛使用。例如,没

我注意到在我的SGI STL参考资料副本中,有一个关于性格特征的页面,但我看不出这些特征是如何使用的?它们是否替换string.h函数?它们似乎没有被
std::string
使用,例如
std::string
上的
length()
方法没有使用字符特征
length()
方法。为什么字符特征存在并且在实践中使用过?

字符特征是流和字符串库的一个极其重要的组成部分,因为它们允许流/字符串类将存储的字符逻辑与应该对这些字符执行的操作逻辑分开人物

首先,C++中的默认字符特征类“代码>字符特征”被广泛使用。例如,没有名为

std::string
的类。相反,有一个类模板
std::basic_string
如下所示:

template <typename charT, typename traits = char_traits<charT> >
    class basic_string;
类似地,标准流定义为

typedef basic_string<char> string;
template <typename charT, typename traits = char_traits<charT> >
    class basic_istream;

typedef basic_istream<char> istream;
也就是说,我可以有一个字符串,其中两个仅区分大小写的字符串比较相等

现在,假设标准库作者设计的字符串没有使用traits。这意味着我在标准库中有一个非常强大的string类,在我的情况下它是完全无用的。我不能重用这个字符串类的大部分代码,因为比较总是与我希望它们的工作方式相反。但是通过使用traits,实际上可以重用驱动
std::string
的代码来获得不区分大小写的字符串

如果你拉上C++ ISO标准的副本,看看字符串比较操作符是如何工作的,你会发现它们都是按照<代码>比较< /Cuff>函数定义的。此函数通过调用

traits::compare(this->data(), str.data(), rlen)
其中,
str
是要比较的字符串,
rlen
是两个字符串长度中较小的一个。这实际上非常有趣,因为这意味着
compare
的定义直接使用
compare
函数,该函数由指定为模板参数的traits类型导出!因此,如果我们定义一个新的traits类,然后定义
compare
,这样它就可以不区分大小写地比较字符,我们可以构建一个字符串类,它的行为就像
std::string
,但不区分大小写

这里有一个例子。我们继承自
std::char\u traits
以获得所有未编写函数的默认行为:

class CaseInsensitiveTraits: public std::char_traits<char> {
public:
    static bool lt (char one, char two) {
        return std::tolower(one) < std::tolower(two);
    }

    static bool eq (char one, char two) {
        return std::tolower(one) == std::tolower(two);
    }

    static int compare (const char* one, const char* two, size_t length) {
        for (size_t i = 0; i < length; ++i) {
            if (lt(one[i], two[i])) return -1;
            if (lt(two[i], one[i])) return +1;
        }
        return 0;
    }
};
瞧!我们现在有一个字符串,它对所有情况都不敏感

当然,除了这一点之外,还有其他原因可以使用特征。例如,如果要定义一个使用固定大小的某个底层字符类型的字符串,则可以对该类型专门化
char\u traits
,然后从该类型生成字符串。例如,在Windows API中,有一个类型
TCHAR
,它是窄字符还是宽字符,取决于您在预处理期间设置的宏。然后,您可以通过编写

typedef basic_string<TCHAR> tstring;
typedef基本字符串;
现在您有了一个字符串
TCHAR
s

在所有这些示例中,请注意,我们只是定义了一些traits类(或使用了一个已经存在的类)作为某个模板类型的参数,以便获取该类型的字符串。整个要点是,
basic_string
作者只需要指定如何使用traits,我们就可以神奇地让他们使用我们的traits,而不是默认的traits,来获得一些不属于默认字符串类型的细微差别或怪癖的字符串

希望这有帮助

<> > >编辑< /St>:正如@ Pooji指出的,这个特性的概念不仅仅是STL使用的,也不是C++特有的。作为一种完全无耻的自我推销,不久前我写过(一种基树),它使用traits来存储任何类型的字符串,并使用客户端希望它们存储的任何比较类型。如果你想看看这在实践中的应用,这可能是一本有趣的书


编辑:针对您声称的
std::string
没有使用
traits::length
,事实证明它在一些地方使用。最值得注意的是,当您从
char*
C样式的字符串中构造
std::string
时,通过对该字符串调用
traits::length
来派生字符串的新长度。似乎<>代码>特性:长度> /CODE >主要用于处理C风格的字符序列,这是C++中字符串的“最小公分母”。虽然
std::string
用于处理任意内容的字符串。

似乎您对用户名做了适当的处理:)也许也有关系:许多boost库使用概念和类型特征类,因此它不仅仅是标准库。此外,在其他语言中也使用了类似的技术,而不使用模板,请参见深奥的示例:。结构很好(三元搜索树),但我要指出的是,尝试可以通过多种方式“压缩”:1/使用字符范围指向子级,而不是单个字符(增益很明显),2/路径压缩(Patricia树)和分支末尾的3/bucket(即,只要少于K,就使用一个排序的字符串数组)。组合这些(我组合了1和3)可以显著减少内存消耗,而不会对速度性能造成超过常量的影响(事实上,bucket减少了跳跃次数)@dan04:尝试使用任何标准类/算法来使用您的函数。因此……简单地说,traits只是基本的_string类用来处理各种类型字符的某种接口,而不管它们实际上是什么
typedef std::basic_string<char, CaseInsensitiveTraits> CaseInsensitiveString;
typedef basic_string<TCHAR> tstring;