Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the purpose of std::char_traits::assign()?

void assign(char_type& to, char_type from);

Why can't you just use the assignment operator instead of using this function? What is this used for?

like image 361
user541686 Avatar asked Aug 19 '12 04:08

user541686


People also ask

What is std :: Char_traits?

std::char_traits The char_traits class is a traits class template that abstracts basic character and string operations for a given character type. The defined operation set is such that generic algorithms almost always can be implemented in terms of it.

What is std :: Basic_string?

std::basic_string is a class template for making strings out of character types, std::string is a typedef for a specialization of that class template for char .


2 Answers

You actually use this function every time you use std::string :). std::string is actually a typedef for std::basic_string, which is defined as:

template< 
    class CharT, 
    class Traits = std::char_traits<CharT>, 
    class Allocator = std::allocator<CharT>
> class basic_string;

(see this). Pay particular attention to the Traits template parameter. If you were so inclined, the Traits template parameter allows you to customize certain attributes of the string class's behavior. One of these properties is what happens when you make an assignment.

Here is an example usage of this. It will force assignments to be lowercase.

#include <string>
#include <iostream>
#include <cctype>

struct ci_char_traits : public std::char_traits<char> {
    static void assign(char& r, const char& a)
    {
        r = std::tolower(a);
    }

    static char* assign(char* p, std::size_t count, char a)
    {
        for (std::size_t i = 0; i < count; ++i)
        {
            p[i] = std::tolower(a);
        }
    }
};

typedef std::basic_string<char, ci_char_traits> ci_string;

std::ostream& operator<<(std::ostream& os, const ci_string& str) {
    return os.write(str.data(), str.size());
}

int main()
{
    ci_string s1 = "Hello";

    // This will become a lower-case 'o'
    s1.push_back('O');

    // Will replace 'He' with lower-case 'a'
    s1.replace(s1.begin(), s1.begin()+2, 1, 'A');

    std::cout << s1 << std::endl;
}
like image 139
nevsan Avatar answered Sep 20 '22 20:09

nevsan


This is because character traits are a way to produce variants of standard classes (like strings) and a primitive type's operator may not actually be what you want.

For instance, consider a class that stores case-insensitive strings; you might implement assign() in a way that stores the same thing for both a capital letter and its lowercase version. (For that matter, other character-trait operations such as equality would have to be overridden too.)

like image 44
Kevin Grant Avatar answered Sep 22 '22 20:09

Kevin Grant