// 型消去を安全に行うクラス
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_;
};