4

私たちのクラスの1つで、先生は、テンプレートを使用するとクラスの動作をカスタマイズできると言い、次に文字列クラスの例を挙げて、数行のコードでSTLから文字列クラスをカスタマイズできると述べました。 a' と 'z' は同じ、'b' と 'y' は同じ、'c' と 'x' は同じなど。同様に、「A」と「Z」も同じです。

"abc" == "zyx" は真です。
"Abc" == "zyx" は偽です。
"Abc == "Zyx" は真です。

そのような文字列クラスを実装しようと考えていましたが、できません。テンプレートを使用してそのような文字列クラスをどのように実装できますか?

4

3 に答える 3

3

とてもトリッキーです。独自の特性char_traits<>クラスを作成するために必要なのは、具体的にはクラス テンプレートから派生させ、eq()およびcompare()関数を再定義することだけです (注: eq()を再定義するだけでは機能しません。compare()の再定義、派生クラスなどに記述する必要があります!)。この traits クラスsequence_traitsを言って、カスタム string を呼び出しましょうsequence。結局のところ、文字列は一連の文字です!

注: あなたの投稿から、あなたがalphabets[i] == alphabets[25-i]同じように扱われたいと私が理解していること、つまり、最初の文字と最後の文字が同じ、2番目の文字と最後の2番目の文字が同じなどです!

struct sequence_traits : char_traits<char>
{
    //'a' and 'z' are equal
    //'b' and 'y' are equal
    //'c' and 'x' are equal, and so on.
    //that implies, 'a' + 'z' == 'b' + 'y' == 'c' + 'x' == 'd'  + 'w == so on
    //same for upper cases!
    static bool eq(const char& left, const char& right)
    {   
        return ( left == right) || (left + right == 'a' + 'z') || ( left + right == 'A' + 'Z') ;
    }
    static int compare(const char *first1, const char *first2, size_t count)
    {   
        for (; 0 < count; --count, ++first1, ++first2)
            if (!eq(*first1, *first2))
                return (lt(*first1, *first2) ? -1 : +1);
        return (0);
    }
};

そして、typedef簡単に使用するためにこれを行うことができます:

typedef basic_string<char, sequence_traits> sequence;

あなたは終わった。今すぐご利用いただけますsequence。:-)

作業例:http ://www.ideone.com/ByBRV


詳細については、この記事をお読みください: http://www.gotw.ca/gotw/029.htm

于 2011-01-04T03:56:17.147 に答える
2

char_traitsタイプを見たいと思うでしょう。これは、機能する文字列型を取得するために basic_string で使用できる特性クラスの 1 つの型の例です。独自の特性クラスを定義する場合、次のようなカスタム文字列を構築できます。

class CustomTraits { ... };
typedef basic_string<char, CustomTraits> CustomString;

そして、CustomTraits によって定義された特性を使用して、文字列がどのように機能するかを決定します。

あなたが言っていたことに沿った例として、次のようなことができます:

class CustomTraits: public char_traits<char> {
public:
    /* Redefine equality to compare 'a' and 'z' equal. */
    static bool eq(char one, char two) {
         return one == two || (one == 'a' && two == 'z' || one == 'z' && two == 'a');
    }
};
typedef basic_string<char, CustomTraits> StringWithAAndZEqual;

これで、新しい型を使用でき、クラスは 'a' と 'z' を同じように扱います。

于 2011-01-04T03:55:29.327 に答える
2

カスタムを作成し、char_traitsそれをインスタンス化する必要がありますstd::basic_string

于 2011-01-04T03:55:51.500 に答える