Implement string class with custom behavior

In one of our classes, sir said that the template allows you to customize the behavior of the class, and then he gave an example of a string class, which with a small number of lines of code can configure the class of strings from STL, as in, we can do this by treating 'a' and ' z 'is the same,' b 'and' y 'are the same,' c 'and' x 'are the same, and so on. Similary 'A' and 'Z' are the same, etc.

"abc" == "zyx" is true;
"Abc" == "zyx" is incorrect,
"Abc ==" Zyx "is true;

etc.

I was thinking about implementing such a string class, but I can't do it. How can we implement such a string class using templates?

+4
source share
3 answers

It is very difficult. All you need to write your own feature class, in particular, you need to extract it from the char_traits<> class template and override the eq () and compare () function (Note: only overriding eq () will not work, even if not changes to override compare () , you have to write it to your derived class as such!). Suppose this class class is sequence_traits and calls your custom string sequence . After all, a string is a sequence of characters!

Note. . I understand from your message that you want alphabets[i] == alphabets[25-i] be considered the same, this means that the first letter and last letter are the same, the second letter and second last letter are the same, and therefore on the!

 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); } }; 

And you can do this typedef for convenience:

 typedef basic_string<char, sequence_traits> sequence; 

You are done. Now you can use sequence . sequence

Working example: http://www.ideone.com/ByBRV


Read this article to find out how it works in detail: http://www.gotw.ca/gotw/029.htm

+3
source

You need to look at char_traits type. This is an example of one type of feature class that you can use with basic_string to get the working type of a string. If you define your own characteristic class, you can create a custom string as follows:

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

And now the traits defined by CustomTraits will be used to determine how the string works.

As an example, according to what you are saying, you can do something like this:

 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; 

Now you can use the new type, and the class will handle "a" and "z" equally.

+2
source

You want to create your own char_traits and create an instance of std::basic_string with this.

+2
source

Source: https://habr.com/ru/post/1334154/


All Articles