オブジェクト インターフェイスと、派生オブジェクトがサポートする可能性があるインターフェイスのオープン エンド コレクションがあります。
// An object
class IObject
{
getAttribute() = 0
}
// A mutable object
class IMutable
{
setAttribute() = 0
}
// A lockable object
class ILockable
{
lock() = 0
}
// A certifiable object
class ICertifiable
{
setCertification() = 0
getCertification() = 0
}
一部の派生オブジェクトは次のようになります。
class Object1 : public IObject, public IMutable, public ILockable {}
class Object2 : public IObject, public ILockable, public ICertifiable {}
class Object3 : public IObject {}
ここに私の質問があります: これらのインターフェースの特定の組み合わせのみを取る関数を書く方法はありますか? 例えば:
void doSomething(magic_interface_combiner<IObject, IMutable, ILockable> object);
doSomething( Object1() ) // OK, all interfaces are available.
doSomething( Object2() ) // Compilation Failure, missing IMutable.
doSomething( Object3() ) // Compilation Failure, missing IMutable and ILockable.
私が見つけた最も近いものはboost::mpl::inheritです。私はいくつかの限られた成功を収めましたが、それは私が必要とすることを正確に行いません。
例えば:
class Object1 : public boost::mpl::inherit<IObject, IMutable, ILockable>::type
class Object2 : public boost::mpl::inherit<IObject, ILockable, ICertifiable>::type
class Object3 : public IObject
void doSomething(boost::mpl::inherit<IObject, ILockable>::type object);
doSomething( Object1() ) // Fails even though Object1 derives from IObject and ILockable.
doSomething( Object2() ) // Fails even though Object2 derives from IObject and ILockable.
boost::mpl::inherit に似たものだと思いますが、提供された型のすべての可能な順列を含む継承ツリーが生成される可能性があります。
この問題を解決するための他のアプローチにも興味があります。理想的には、実行時ではなくコンパイル時のチェックを行うもの (つまり、dynamic_cast なし) です。