Хорошо, это немного сложно, поэтому, пожалуйста, потерпите меня.:)
class A {};
class DA : public A {};
class DDA : public DA {};
void f(A x) {
std::cout << "f A" << std::endl;
}
void f(DA x) {
std::cout << "f DA" << std::endl;
}
void f(DDA x) {
std::cout << "f DDA" << std::endl;
}
Теперь мы хотим добавить еще одну функцию, которая немного по-другому обрабатывает DA.
void g(A t) {
std::cout << "generic treatment of A" << std::endl;
std::cout << "called from g: ";
f(t);
}
void g(DA t) {
std::cout << "special treatment of DA" << std::endl;
std::cout << "called from g: ";
f(t);
}
Но вызов этого с объектом каждого из классов явно не дает желаемого эффекта.
Звоните:
A a; DA b; DDA c;
g(a); g(b); g(c)
Результат:
generic treatment of A
called from g: f A
special treatment of DA
called from g: f DA
special treatment of DA
called from g: f DA //PROBLEM: g forgot that this DA was actually a DDA
template
void h(T t) {
std::cout << "generic treatment of A" << std::endl;
std::cout << "called from h: ";
f(t);
}
template<>
void h<>(DA t) {
std::cout << "special treatment of DA" << std::endl;
std::cout << "called from h: ";
f(t);
}
что приводит к:
generic treatment of A
called from h: f A
special treatment of DA
called from h: f DA
generic treatment of A //PROBLEM: template specialization is not used
called from h: f DDA
Хорошо, а как насчет того, чтобы не использовать специализацию шаблона, а определить функцию шаблона, отличную от -, для особого случая?(Статья по очень запутанному делу. )Оказывается, он ведет себя точно так же, потому что не--шаблонная функция, которая, согласно статье, является "гражданином первого сорта", похоже, проигрывает, потому что для ее использования необходимо преобразование типа. А если бы его использовали, то мы просто вернулись бы к первому решению (я полагаю )и забыли бы о типе DDA.
template
void i(T t, void* magic) {
std::cout << "generic treatment of A" << std::endl;
std::cout << "called from i: ";
f(t);
}
template
void i(T t, DA* magic) {
std::cout << "special treatment of DA" << std::endl;
std::cout << "called from i: ";
f(t);
}
Но, похоже, он делает именно то, что я хочу:
generic treatment of A
called from i: f A
special treatment of DA
called from i: f DA
special treatment of DA
called from i: f DDA
Несмотря на то, что он должен называться как-то странно :я (а, &а ); я (б, &б ); я (с, и с );
Теперь у меня есть несколько вопросов:
Надеюсь, это было достаточно ясно.:)