Как заставить тип шаблона в MyClass соответствовать типу
наследование как в классе Observed: публичный MyClass. Что такое
лучший подход здесь?
Это можно сделать и во время компиляции. Вероятно, для обработчика Observer наиболее целесообразно выполнить проверку. Добавьте тип, скажем DerivedType, в MyClass, который обработчик может проверить:
template <typename TT>
class MyClass
{
public:
typedef TT DerivedType;
};
template <typename AA, typename BB>
struct SameType;
template <typename AA>
struct SameType<AA, AA> {};
class AnyObserver
{
public:
template <typename VV>
void HandleObserved(VV&)
{
std::cout << "Observed\n";
SameType<VV, VV::DerivedType>();
}
};
Если VV не является производным от MyClass, то HandleObserved () не сможет скомпилироваться, поскольку SameType будет успешным, только если VV имеет тип DerivedType в качестве члена, и если VV и VV :: DerivedType имеют одинаковый тип, который может случается только если VV наследуется от MyClass. Некоторые примеры наблюдаемых:
class Derived: public MyClass<Derived>
{
};
class NotDerived
{
};
class Foo
{
};
class BadDerived1: public MyClass<Foo>
{
};
class BadDerived2: public MyClass<Derived>
{
};
И тест, который показывает код для этих наблюдаемых, вызывающий ошибку во время компиляции:
void test()
{
Derived foo; // ok
NotDerived bad1; // ok so far
BadDerived1 bar1; // ok so far
BadDerived2 bar2; // ok so far
AnyObserver obs;
obs.HandleObserved(foo); // ok
//obs.HandleObserved(bad1); // BANG! at compile time
//obs.HandleObserved(bar1); // BANG! at compile time
//obs.HandleObserved(bar2); // BANG! at compile time
}
Я не пробовал с VS2010, только 2005.