void assign(char_type& to, char_type from);
为什么不能使用赋值运算符而不是this function?这是用来做什么的?
答案 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=
。但是,您可能会发现使用char
,wchar_t
,char16_t
,char32_t
或char8_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);