void assign(char_type& to, char_type from);
この関数を使用する代わりに、代入演算子を使用できないのはなぜですか? これは何に使われますか?
void assign(char_type& to, char_type from);
この関数を使用する代わりに、代入演算子を使用できないのはなぜですか? これは何に使われますか?
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;
(これを参照)。Traits テンプレート パラメータに特に注意してください。気が向いたら、Traits テンプレート パラメーターを使用すると、文字列クラスの動作の特定の属性をカスタマイズできます。これらのプロパティの 1 つは、割り当てを行うときに何が起こるかです。
これの使用例を次に示します。割り当てが小文字になるように強制します。
#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;
}
これは、文字特性が標準クラス (文字列など) のバリアントを生成する方法であり、プリミティブ型の演算子が実際に必要なものではない可能性があるためです。
たとえば、大文字と小文字を区別しない文字列を格納するクラスを考えてみましょう。assign()
大文字と小文字のバージョンの両方に同じものを格納する方法で実装できます。(さらに言えば、等値などの他の文字特性操作もオーバーライドする必要があります。)