std :: char_traits :: assign()的目的是什么?

时间:2012-08-19 04:30:54

标签: c++ char char-traits

void assign(char_type& to, char_type from);

为什么不能使用赋值运算符而不是this function?这是用来做什么的?

3 个答案:

答案 0 :(得分:8)

每次使用std :: string :)时,实际上都使用此函数。 std :: string实际上是std :: basic_string的typedef,定义为:

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

(见this)。特别注意Traits模板参数。如果您如此倾向,Traits模板参数允许您自定义字符串类行为的某些属性。其中一个属性是您进行作业时会发生的情况。

以下是此示例用法。它会强制分配小写。

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

答案 1 :(得分:3)

这是因为角色特征是产生标准类变体的一种方式(如字符串),而原始类型的操作符可能实际上并不是你想要的。

例如,考虑一个存储不区分大小写的字符串的类;您可以以对大写字母及其小写版本存储相同内容的方式实现assign()。 (就此而言,其他角色特征操作,例如平等也必须被覆盖。)

答案 2 :(得分:0)

您可以编写自己的字符类,并定义其operator=。但是,您可能会发现使用charwchar_tchar16_tchar32_tchar8_t等基本字符类型会很方便。此类非类类型不允许您重载其运算符,因此char_traits提供了一种自定义其通用操作的小集合的方法(如其他答案所建议,这可以允许不区分大小写的字符操作,例如)。

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

std::basic_string是一个很好的例子;第二个模板参数Traits允许访问此类自定义。还考虑第三个模板参数Allocator,它允许std::basic_string的用户自定义其内部分配内存的方式。这可能会导致类似的问题:为什么不只使用operator new

意义不大,但也请注意,C ++ 20引入了第二个std::char_traits<CharT>::assign重载:

static constexpr char_type* assign(char_type* p, std::size_t count, char_type a);