Посмотрите на функции position()
, count()
и last()
; например, test="position() < last()"
.
В панели классов добавьте
using foo::a;
. Это обычная ошибка в C ++. Как только совпадение имени найдено в области класса a, он не ищет перегрузок по дереву наследования. Задавая объявление using, вы переносите все перегрузки a из foo в область действия bar. Тогда перегрузка работает правильно.
Помните, что если существует код, использующий класс 'foo', его значение может быть изменено дополнительными перегрузками. Или дополнительные перегрузки могут внести двусмысленность, и код не будет скомпилирован. На это указывает ответ Джеймса Хопкина.
Именно так работал язык. До с использованием ключевого слова , если вы переопределяли одну перегруженную функцию, вам приходилось перегружать их все:
class bar : public foo
{
public:
bar(void);
~bar(void);
a(int);
a(double d) { foo::a(d); } // add this
}
Это настолько раздражало людей, что языковой комитет добавил , используя функцию , но некоторые Старые привычки умирают с трудом; и у постоянных посетителей есть веские аргументы.
Как указывает Джеймс Хопкинс, добавляя с помощью , программист выражает намерение, что производный класс без предупреждения добавит любые будущие переопределения foo: : a () в список допустимых подписей.
Вот пример того, что он описывает:
#include <iostream>
class Base {
public:
virtual void f(double){ std::cout << "Base::Double!" << std::endl; }
// virtual void f(int) { std::cout << "Base::Int!" << std::endl; } // (1)
virtual ~Base() {}
};
class Derived : public Base {
public:
// using Base::f; // (2)
void f(double) { std::cout << "Derived::Double!" << std::endl; }
};
int main(int, char **) {
Derived d;
d.f(21);
return 0;
}
Результатом будет "Derived :: Double!" потому что компилятор преобразует целочисленный аргумент в двойной. g ++ 4.0.1 -Wall не будет предупреждать о том, что это продвижение произошло.
Раскомментируйте (1), чтобы смоделировать будущие изменения в Base, добавив метод Base :: f (int). Код компилируется, опять же без предупреждения, даже с -Wall и "Derived :: Double!" остается выходом.
Теперь раскомментируйте (2), чтобы смоделировать решение производного программиста включить все сигнатуры Base :: f. Код компилируется (без предупреждений), но теперь на выходе получается «Base :: Int!».
-
† Я не могу придумать английского слова для обозначения «те, у кого есть привычка», а «зависимый» - это много слишком сильно.
Это сделано специально. Разрешение перегрузки ограничено одной областью. Это предотвращает некоторые неприятные случаи изменения значения допустимого кода при добавлении дополнительных функций к базовому классу или в область видимости пространства имен.