- 型消去とは「任意の型の値に対して型情報を不要とする値に変換する技法」のこと
- 「型情報を持たないデータ」と「型情報の復元を行う処理」に分けることで実現する
- 型情報が不要となることで、任意の値を格納できるクラスなどを定義できる
- C++では、型消去を安全に行うためのクラスを定義できる
- テンプレートを用いて任意の型の値を受け入れ、サブタイピングを用いた可搬な値に変換して保持する
- クラスでラップすることで生のポインタを扱うよりも高機能になる
- コピーやムーブを安全に行える
- Copy On WriteやSmall Buffer Optimizationなどの最適化も実装できる
- 標準では
std::functionやstd::anyなどが型消去を用いて実装されている
コード例#
// 型消去を安全に行うクラス
class TypeErased {
private:
// 処理を記述するための基底クラス
struct Base {
virtual ~Base() = default;
virtual void foo() = 0;
};
public:
// 任意の型の値を受け入れるコンストラクタ
template <typename T>
explicit TypeErased(T&& value) {
// 値を保持するための派生クラス
class Derived : public Base {
public:
Derived(T&& value) : value_(std::forward<T>(value)) {}
void foo() override {
// 仮想関数の実装が型情報の復元を担う
value_.bar();
}
private:
T value_;
};
// 値が格納された派生クラスを基底クラスとして保持する
ptr_ = make_unique<Derived>(std::forward<T>(value));
}
// 処理を呼び出す
void foo() {
if (ptr_) ptr_->foo();
}
private:
std::unique_ptr<Base> ptr_;
};