I notice that in my copy of the SGI STL reference, there is a page about Character Traits but I can't see how these are used? Do they replace the string.h functions? They don't seem to be used by std::string, e.g. the length() method on std::string doesn't make use of the Character Traits length() method. Why do Character Traits exist and are they ever used in practice?
What is the point of STL Character Traits?
15.6k Views Asked by Matthew Smith At
1
There are 1 best solutions below
Related Questions in C++
- How to immediately apply DISPLAYCONFIG_SCALING display scaling mode with SetDisplayConfig and DISPLAYCONFIG_PATH_TARGET_INFO
- Why can't I use templates members in its specialization?
- How to fix "Access violation executing location" when using GLFW and GLAD
- Dynamic array of structures in C++/ cannot fill a dynamic array of doubles in structure from dynamic array of structures
- How do I apply the interface concept with the base-class in design?
- File refuses to compile std::erase() even if using -std=g++23
- How can I do a successful map when the number of elements to be mapped is not consistent in Thrust C++
- Can std::bit_cast be applied to an empty object?
- Unexpected inter-thread happens-before relationships from relaxed memory ordering
- How i can move element of dynamic vector in argument of function push_back for dynamic vector
- Brick Breaker Ball Bounce
- Thread-safe lock-free min where both operands can change c++
- Watchdog Timer Reset on ESP32 using Webservers
- How to solve compiler error: no matching function for call to 'dmhFS::dmhFS()' in my case?
- Conda CMAKE CXX Compiler error while compiling Pytorch
Related Questions in STRING
- What does: "char *argv[]" mean?
- User input sanitization program, which takes a specific amount of arguments and passes the execution to a bash script
- JSON Body is Not Passing Certain Strings
- Regex to match repeated substring in Google Sheets
- Find the sum of the numbers in the sequence
- Hello, how can I use a block parameter of withstyle parameter when we create a annotated string in jetpackpack compose
- How to convert an HTML string to an escaped one?
- Quintic Number Number Counting Hash Function
- From Buffer("string", "hex) to string JS
- Calling ToString with a nominated format returns Char rather than String
- How to update an already existing array by accessing it by a variable with the exact same name assigned to it
- Why does \b not interpreted as backslash in this regular expression
- Python: why aren’t strings being internalized if they are received from ints by using str()?
- If the element(s) in the first list equal element(s) of the second list, replace with element(s) of the third list
- About Suffix Trees features
Related Questions in STL
- Why my code is working on everything except one instance?
- Why does the map size change?
- C++ ordered map optimized with index access
- Circular extention to std::array
- Is there a chance to use a custom std::pmr::polymorphic_allocator to make std::unordered_map’s buckets implemented as arrays?
- STL: Keeping Only Unique String Characters AND Preserving Order
- Importing <filesystem> in gcc
- Are there any iterator invalidation rules for <algorithms> operations?
- Check if Array Is Sorted and Rotated on LeetCode
- std::shared_mutex::unlock_shared() blocks even though there are no active exclusive locks on Windows
- could the type of std::map's key be double or float?
- How to implement an iterator for a two leveled map in C++?
- Why does priority_queue use greater<> for ascending order?
- Scope of C++ references and STL containers
- Implement Non Copyable Non Moveable wrapper for map/vector etc
Related Questions in STDSTRING
- Do I need to free a character buffer after passing it to std::string()?
- Why do the const accessors of std::string return a reference?
- Convert boost::container::boost basic_string to std::string
- Using zlib for std::string and stringstream
- How to get a writable C buffer from std::string?
- Substring of a std::string in utf-8? C++11
- what is the correct way to concat strings in c++ and execute using system
- Lifetime of returned strings and their .c_str()
- Using strings in switch statements - where do we stand with C++17?
- Assure correct string input in C++
- How to convert std::string to std::u32string?
- User input filename
- std::string with stateful Allocator
- No operator ">>" for std::string>>std::string
- About the underlying storage of std::basic_string
Related Questions in CHAR-TRAITS
- C++ Builder 11 linker problem - Unresolved external 'std::char_traits<char>::assign(char *, unsigned int, char)
- How to initialize custom analogue for std::cout?
- Why does std::basic_string have two separate template parameters _Elem (char type) and _Traits (char traits)?
- How to assign a std::string to std::basic_string<unsigned short int, TRAITS_CLASS>(Unicode2String) on Linux
- Is it guaranteed that std::char_traits<char>::to_int_type(c) == static_cast<int>(c)?
- Why std::basic_fstream<unsigned char> won't work?
- Is it possible to use std::char_traits<char> in constant expressions before GCC 8?
- removing constexpr from a variable capturing a constexpr function return value removes compile-time evaluation
- Leading/trailing whitespace insensitive traits for basic_string
- VS 2015 std::char_traits<char16_t> operations
- How one can safely serialize std::basic_istream<char>::pos_type?
- Convert std::string to ci_string
- How can I use char_traits algorithms with a custom iterator type?
- How to read cstrings from char**?
- Why does this specialized char_traits<uint8_t> and codecvt<uint8_t> for use with the basic_ifstream template throw std::bad_cast?
Trending Questions
- UIImageView Frame Doesn't Reflect Constraints
- Is it possible to use adb commands to click on a view by finding its ID?
- How to create a new web character symbol recognizable by html/javascript?
- Why isn't my CSS3 animation smooth in Google Chrome (but very smooth on other browsers)?
- Heap Gives Page Fault
- Connect ffmpeg to Visual Studio 2008
- Both Object- and ValueAnimator jumps when Duration is set above API LvL 24
- How to avoid default initialization of objects in std::vector?
- second argument of the command line arguments in a format other than char** argv or char* argv[]
- How to improve efficiency of algorithm which generates next lexicographic permutation?
- Navigating to the another actvity app getting crash in android
- How to read the particular message format in android and store in sqlite database?
- Resetting inventory status after order is cancelled
- Efficiently compute powers of X in SSE/AVX
- Insert into an external database using ajax and php : POST 500 (Internal Server Error)
Popular Questions
- How do I undo the most recent local commits in Git?
- How can I remove a specific item from an array in JavaScript?
- How do I delete a Git branch locally and remotely?
- Find all files containing a specific text (string) on Linux?
- How do I revert a Git repository to a previous commit?
- How do I create an HTML button that acts like a link?
- How do I check out a remote Git branch?
- How do I force "git pull" to overwrite local files?
- How do I list all files of a directory?
- How to check whether a string contains a substring in JavaScript?
- How do I redirect to another webpage?
- How can I iterate over rows in a Pandas DataFrame?
- How do I convert a String to an int in Java?
- Does Python have a string 'contains' substring method?
- How do I check if a string contains a specific word?
Character traits are an extremely important component of the streams and strings libraries because they allow the stream/string classes to separate out the logic of what characters are being stored from the logic of what manipulations should be performed on those characters.
To begin with, the default character traits class,
char_traits<T>, is used extensively in the C++ standard. For example, there is no class calledstd::string. Rather, there's a class templatestd::basic_stringthat looks like this:Then,
std::stringis defined asSimilarly, the standard streams are defined as
So why are these classes structured as they are? Why should we be using a weird traits class as a template argument?
The reason is that in some cases we might want to have a string just like
std::string, but with some slightly different properties. One classic example of this is if you want to store strings in a way that ignores case. For example, I might want to make a string calledCaseInsensitiveStringsuch that I can haveThat is, I can have a string where two strings differing only in their case sensitivity are compared equal.
Now, suppose that the standard library authors designed strings without using traits. This would mean that I'd have in the standard library an immensely powerful string class that was entirely useless in my situation. I couldn't reuse much of the code for this string class, since comparisons would always work against how I wanted them to work. But by using traits, it's actually possible to reuse the code that drives
std::stringto get a case-insensitive string.If you pull up a copy of the C++ ISO standard and look at the definition of how the string's comparison operators work, you'll see that they're all defined in terms of the
comparefunction. This function is in turn defined by callingwhere
stris the string you're comparing to andrlenis the smaller of the two string lengths. This is actually quite interesting, because it means that the definition ofcomparedirectly uses thecomparefunction exported by the traits type specified as a template parameter! Consequently, if we define a new traits class, then definecompareso that it compares characters case-insensitively, we can build a string class that behaves just likestd::string, but treats things case-insensitively!Here's an example. We inherit from
std::char_traits<char>to get the default behavior for all the functions we don't write:(Notice I've also defined
eqandlthere, which compare characters for equality and less-than, respectively, and then definedcomparein terms of this function).Now that we have this traits class, we can define
CaseInsensitiveStringtrivially asAnd voila! We now have a string that treats everything case-insensitively!
Of course, there are other reasons besides this for using traits. For example, if you want to define a string that uses some underlying character type of a fixed-size, then you can specialize
char_traitson that type and then make strings from that type. In the Windows API, for example, there's a typeTCHARthat is either a narrow or wide character depending on what macros you set during preprocessing. You can then make strings out ofTCHARs by writingAnd now you have a string of
TCHARs.In all of these examples, notice that we just defined some traits class (or used one that already existed) as a parameter to some template type in order to get a string for that type. The whole point of this is that the
basic_stringauthor just needs to specify how to use the traits and we magically can make them use our traits rather than the default to get strings that have some nuance or quirk not part of the default string type.EDIT: As @phooji pointed out, this notion of traits is not just used by the STL, nor is it specific to C++. As a completely shameless self-promotion, a while back I wrote an implementation of a ternary search tree (a type of radix tree described here) that uses traits to store strings of any type and using whatever comparison type the client wants them to store. It might be an interesting read if you want to see an example of where this is used in practice.
EDIT: In response to your claim that
std::stringdoesn't usetraits::length, it turns out that it does in a few places. Most notably, when you construct astd::stringout of achar*C-style string, the new length of the string is derived by callingtraits::lengthon that string. It seems thattraits::lengthis used mostly to deal with C-style sequences of characters, which are the "least common denominator" of strings in C++, whilestd::stringis used to work with strings of arbitrary contents.