Следуя методам 'Modern C ++ Design', я реализую библиотеку постоянства с различными оптимизациями во время компиляции. Мне бы хотелось иметь возможность отправлять функцию в шаблонную переменную-член, если эта переменная является производной от данного класса:
template<class T, template <class> class Manager = DefaultManager> class Data
{
private:
T *data_;
public:
void Dispatch()
{
if(SUPERSUBCLASS(Container, T))
{
data_->IKnowThisIsHere();
}
else
{
Manager<T>::SomeGenericFunction(data_);
}
}
}
Где SUPERSUBCLASS - это макрос времени компиляции для определения наследования объектов. Конечно, это терпит неудачу во всех случаях, когда T наследуется от Container (или T является внутренним типом и т. Д. И т. Д.), Потому что компилятор справедливо жалуется, что IKnowThisIsHere () не является членом данных, даже если этот путь кода никогда не будет следовать как показано здесь после предварительной обработки с T = int:
private:
int *data_;
public:
void Dispatch()
{
if(false)
{
data_->IKnowThisIsHere();
Компилятор явно жалуется на этот код, даже если он никогда не будет выполнен. Предложение использовать dynamic_cast также не работает, так как снова попытка преобразования типа во время компиляции невозможна (например, с T = double, std :: string):
void Dispatch()
{
if(false)
{
dynamic_cast<Container*>(data_)->IKnowThisIsHere();
error: cannot dynamic_cast '((const Data<double, DefaultManager>*)this)->Data<double, DefaultManager>::data_' (of type 'double* const') to type 'class Container*' (source is not a pointer to class)
error: cannot dynamic_cast '((const Data<std::string, DefaultManager>*)this)->Da<sttad::string, DefaultManager>::data_' (of type 'struct std::string* const') to type 'class Container*' (source type is not polymorphic)
Мне действительно нужно эмулировать (или даже убедить!), Чтобы компилятор выдавал один набор кода, если T наследовал от Container, и другой, если это не так.
Есть предложения?