2006-03-14
引き続き固定長文字列クラスの話題です。前回、固定長文字列クラスを設計する上での問題点として、固定長文字列クラスから暗黙的に変換可能な共通クラスが必要だということを書きました。共通のクラスに変換できないと、固定長文字列を引数として受け取る関数は常にテンプレートにしなければならなくなってしまいます。
最も素直な解法は、固定長文字列クラステンプレートに共通の基底クラスを作ってしまう方法です。先に紹介した Boost から却下された fixed_string ライブラリもこの方法を採っていました。しかし、如何せん仮想デストラクタを使っているところがよくありません。
かなり前にお話したように、本当に必要でもない状況で仮想デストラクタを使うのは、効率に重大な問題を及ぼします。ですから、ここは別の解法を考えてみたいと思います。もちろん、暗黙に変換されるクラスなど不要で、.c_str() メンバ関数で const char* にしてしまえばよいという考え方もありますが、やはりクラスにしておいた方が何かと便利です。
基底クラスが使えないのであれば、暗黙的に変換可能なクラスとしては、変換コンストラクタを持った別のクラス以外にありません。
class fixed_string_ref
{
public:
template <std::size_t N>
fixed_string_ref(const fixed_string<N>& src);
...
private:
char* data_;
std::size_t size_;
};
のように、テンプレートを外すための別クラスを作ることでこの問題は解決しそうです。何なら、デフォルトコンストラクタを定義しなければ、fixed_string からの変換か、コピーコンストラクタ以外での生成方法がなくなりますので、誤用を防ぐこともできそうです。
Comment