Предполагая, что у меня было два класса, первые из них для записи примитивных типов (bool
, int
, float
и т.д.), а второй проход первого и писать сложные типы:Почему C++ предпочитает этот метод шаблона методу перегрузки?
struct Writer {
virtual void Write(int value) = 0;
};
struct ComplexWriter : public Writer {
template <typename TValue> void Write(const TValue &value) {
boost::any any(value);
Write(any);
}
//virtual void Write(int value) = 0; // see question below
virtual void Write(const boost::any &any) = 0;
};
Идея заключается в том, что если кто-то звонит myWriter.Write(someIntValue);
, перегрузка int получит приоритет над шаблоном.
Вместо этого мой компилятор (Visual C++ 11.0 RC) всегда выбирает метод шаблона. Следующий фрагмент кода, например, будет печатать Wrote any
на консоль:
struct ComplexWriterImpl : public ComplexWriter {
virtual void Write(int value) { std::cout << "Wrote an int"; }
virtual void Write(const boost::any &any) { std::cout << "Wrote any"; }
};
void TestWriter(ComplexWriter &writer) {
int x = 0;
writer.Write(x);
}
int main() {
ComplexWriterImpl writer;
TestWriter(writer);
}
поведение резко меняется, когда я объявляю метод Write(int)
в ComplexWriter
классе, а также (см закомментирована строку в первом фрагменте). Затем он выводит на консоль Wrote an int
.
Это как мой компилятор должен вести себя? Является ли стандарт C++ явно сказать, что только перегрузки, определенные в одном классе (а не базовом классе), должны быть приоритетными по шаблонизированному методу?
Я не вижу, где вы перегрузить метод, принимающий Int с одним шаблонными. У вас есть два несвязанных класса: 'Writer' с методом, принимающим' int' и 'ComplexWriter' с шаблонизированным методом (и методом' boost :: any const & '). В вашем тестовом коде вы используете 'ComplexWriter', поэтому, конечно, он будет называть членом' ComplexWriter'. Если вы действительно ожидали, что он назовет члена совершенно несвязанного класса 'Writer', вы можете объяснить, почему (и как) он должен это делать? – celtschk
Вы упомянули, что 'ComplexWriter' расширяет' Writer', но в коде, который вы указали, он не наследуется от 'Writer'. Это правильная настройка? – Attila
Спасибо, что указали это. Да, ComplexWriter должен был получить от Writer. Я соответствующим образом обновил этот вопрос. Результат все тот же (хотя, конечно, забывая указать, что базовый класс подключается к ядру моего вопроса.). – Cygon