2018年03月14日
《その331》 char_traits 構造体
char_traits<char>
クラステンプレート basic_string は、次のような形式になっています。
template<
class CharT,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>
> class basic_string;
string は basic_string<char> と同義ですから、Traits と Allocator はデフォルトの指定になっています。
したがって、string とは、
class basic_string<
char,
char_traits<char>,
allocator<char>
>
のことです。
下記のプログラムでは、主にクラスの振る舞いに関する関数を実装する Traits に
char_traits<char> ではなく、
char_traits2<char> を使います。
char_traits2<char> は、char_traits<char> から public派生したもので、
文字が等しいかどうかの比較の際に大文字/小文字を区別しない点だけが、
基底クラス char_traits<char> と異なっています。
新しいクラスは、Traits が異なっているため、string とは別のクラスなので、string2 と名付けました。
typedef
class basic_string<char, char_traits2<char>,
allocator<char> >
strind2;
前述したことの繰り返しになりますが、string2型の場合、文字の比較の際に大文字/小文字を区別しません。
以下は、プログラムです。
#include <string>
#include <iostream>
#include <cctype>
struct char_traits2
: public std::char_traits<char> {
static char toup(char ch) {
return std::toupper((char)ch);
}
static bool eq(char c1, char c2) {
return toup(c1) == toup(c2);
}
static int compare(
const char_type* s1,
const char_type* s2,
std::size_t count
) {
while (count-- != 0) {
if (!eq(*s1, *s2))
return 1;
++s1; ++s2;
}
return 0;
}
};
typedef std::basic_string<char, char_traits2>
string2;
std::ostream& operator<<(
std::ostream& os,
const string2& str
) {
for (unsigned i = 0; i < str.size(); i++)
os << str[i];
return os;
}
void disp(string2 x1, string2 x2, int f) {
char c = (f == 1) ? '=' : '!';
std::cout << "\"" << x1 << "\" " << c
<< "= \"" << x2 << "\"\n";
}
int main() {
string2 a0 = "abcdefgh";
string2 a1 = "ABCDEFGH";
disp(a0, a1, a0 == a1);
string2 a2 = "STuvwxyZ";
string2 a3 = "stUVWXYz";
disp(a2, a3, a2 == a3);
string2 a4 = "STuvsxyZ";
string2 a5 = "slUVWXYz";
disp(a4, a5, a4 == a5);
}
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7432069
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック