Стандарты программирования на С++. 101 правило и рекомендация | страница 119



когда шаблон класса наследуется от одного из параметров этого шаблона (например, >T в случае >templateclass С:T{};) или от типа, который построен с использованием одного из параметров шаблона (например, >X в случае >templateclass C:X{};).

Коротко говоря, при обращении к любому члену зависимого базового класса необходимо всегда явно квалифицировать имя с использованием имени базового класса или при помощи >this->. Этот способ можно рассматривать просто как некую магию, которая заставляет все компиляторы делать именно то, что вы от них хотите.

>template

>class С : X {

> typename X::SomeType s; // Использование вложенного

>                            // типа (или синонима

>                            // typedef) из базового

>                            // класса

>public:

> void f() {

>  X::baz();              // вызов функции-члена

>                            // базового класса

>  this->baz();              // Альтернативный способ

> }

>};

Стандартная библиотека С++ в основном отдает предпочтение варианту 2 (например, >ostream_iterator ищет оператор >operator<<, a >accumulate ищет оператор >operator+ в пространстве имен вашего типа). В некоторых местах стандартная библиотека использует также вариант 3 (например, >iterator_traits, >char_traits) в основном потому, что эти классы свойств должны быть специализируемы для встроенных типов.

Заметим, что, к сожалению, стандартная библиотека С++ не всегда четко определяет точки настройки некоторых алгоритмов. Например, она ясно говорит о том, что трехпараметрическая версия >accumulate должна вызывать пользовательский оператор >operator+ с использованием второго варианта. Однако она не говорит, должен ли алгоритм >sort вызывать пользовательскую функцию >swap (обеспечивая таким образом преднамеренную точку настройки с использованием варианта 2), может ли он использовать пользовательскую функцию >swap, и вызывает ли он функцию >swap вообще; на сегодняшний день некоторые реализации >sort используют пользовательскую функцию >swap, в то время как другие реализации этого не делают. Важность рассматриваемой рекомендации была осознана совсем недавно, и сейчас комитет по стандартизации исправляет ситуацию, устраняя такие нечеткости из стандарта. Не повторяйте такие ошибки. (См. также рекомендацию 66.)

Ссылки

[Stroustrup00] §8.2, §10.3.2, §11.2.4 • [Sutter00] §31-34 • [Sutter04d]

66. Не специализируйте шаблоны функций

Резюме

При расширении некоторого шаблона функции (включая