Чтение онлайн

на главную - закладки

Жанры

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

Александреску Андрей

Шрифт:

Второй вариант представляет собой использование метода "неявного интерфейса", но с функциями, не являющимися членами, поиск которых выполняется с использованием ADL [3] (т.е. ожидается, что данная функция находится в пространстве имен типа, для которого выполняется инстанцирование шаблона). Именно эта ситуация и явилась основной побудительной причиной для введения ADL (см. рекомендацию 57). Ваш шаблон рассчитывает на то, что для используемого типа имеется подходящая функция с заданным именем:

3

Поиск,

зависящий от аргумента (см. стр. 118). — Прим. перев.

// Вариант 2: Создание точки настройки путем требования от

// типа T "fоо-совместимости", т.е. наличия функции, не

// являющейся членом с данным именем, сигнатурой и

// семантикой, поиск которой выполняется посредством ADL.

// (Это единственный вариант, при котором не требуется поиск

// самого типа T.)

template<typename T>

void Samplе2(T t) {

 foo(t); // foo - точка настройки

 cout << t; // Еще один пример - operator<< с записью в

} // виде оператора представляет собой такую же

// точку настройки

Для реализации варианта 2 автор

Samplе2
должен выполнить следующие действия.

• Вызвать функцию с использованием неквалифицированного имени (включая использование естественного синтаксиса в случае операторов) и убедиться, что шаблон не имеет функции-члена с тем же именем. В случае шаблонов очень важно, чтобы вызов функции был не квалифицированным (например, не следует писать

SomeNamespace::foo(t)
) и чтобы у шаблона не было функции-члена с тем же именем, поскольку в обоих этих случаях поиск, зависящий от аргумента, выполняться не будет, что предотвратит поиск имени в пространстве имен, в котором находится тип
T
.

• Документировать точку настройки. Тип должен обеспечить наличие функции, не являющейся членом, которая может быть вызвана с данными аргументами.

Варианты 1 и 2 имеют одинаковые преимущества и применимость: пользователь может один раз написать соответствующую функцию настройки для своего типа и разместить ее там, где ее смогут найти и шаблоны других библиотек. Тем самым пользователь избегает необходимости писать множество мелких адаптеров для каждой библиотеки отдельно. Недостаток же заключается в том, что соответствующая семантика должна быть достаточно широко применима и иметь смысл для всех такого рода потенциальных применений (заметим, что в частности в эту категорию попадают операторы, что является еще одной причиной для рекомендации 26).

Третий вариант заключается в использовании специализации, когда ваш шаблон полагается на то, что пользовательский тип специализирует (при необходимости) некоторый иной предоставленный вами шаблон класса.

// Вариант 3: Создание точки настройки путем требования от

// типа T "foo-совместимости"
путем специализации шаблона

// SampleTraits<> с предоставлением (обычно статической)

// функции с данным именем, сигнатурой и семантикой.

template<typename T>

void Samplе3(T t) {

 S3Traits<T>::foo(t); // S3Traits<>::foo -

// точка настройки

 typename S3Traits<T>::value_type x; // Другой пример -

} // точка настройки для поиска типа (обычно

// создается посредством typedef)

В этом варианте пользователь пишет адаптер, который гарантирует изолированность кода настройки для данной библиотеки в пределах этой библиотеки. Соответствующий недостаток заключается в том, что это может оказаться слишком громоздким решением; если несколько библиотек шаблонов требуют одну и ту же общую функциональность, пользователь должен будет писать несколько адаптеров, по одному для каждой библиотеки.

Для реализации этой версии автор

Samplе3
должен выполнить следующие действия.

• Предоставить шаблон класса по умолчанию в собственном пространстве имен шаблона. Не используйте шаблоны функций, которые нельзя частично специализировать и которые приводят к перегрузкам и зависимостям от порядка (см. также рекомендацию 66).

• Документировать точку настройки. Пользователь должен специализировать

S3Traits
для своего собственного типа в пространстве имен библиотеки шаблонов, и документировать все члены
S3Traits
(например,
foo
) и их семантику.

При использовании любого из перечисленных вариантов следует также четко документировать семантику, требуемую от foo, в особенности все существенные действия (постусловия), которые должна гарантировать эта функция, и семантику сбоев (что именно происходит при сбое и каким образом должно осуществляться оповещение об ошибках).

Если точка настройки должна действовать и для встроенных типов, используйте варианты 2 и 3.

Варианты 1 и 2 следует предпочесть для тех общих операций, которые являются предоставляемыми типом сервисами. Для принятия данного решения попробуйте ответить на следующие вопросы: могут ли другие библиотеки шаблонов использовать данную возможность? является ли рассматриваемая семантика приемлемой для данного имени в общем случае? Если вы положительно ответили на эти вопросы, то, вероятно, вам действительно следует предпочесть один из этих вариантов.

Вариант 3 лучше использовать для менее общих операций, смысл которых может варьироваться. В таком случае в другом пространстве имен без каких-либо коллизий вы сможете придать тому же имени иной смысл.

Шаблон, в котором имеется несколько точек настройки, для каждой из них может выбрать свою стратегию, в наибольшей мере приемлемую в данном месте. Главное, что вы должны осознанно, с пониманием выбирать стратегию для каждой точки настройки, документировать требования к настройке (включая ожидаемые постусловия и семантику ошибок) и корректно реализовать выбранную вами стратегию.

Поделиться:
Популярные книги

Блуждающие огни 4

Панченко Андрей Алексеевич
4. Блуждающие огни
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Блуждающие огни 4

Я сделаю это сама

Кальк Салма
1. Магический XVIII век
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Я сделаю это сама

Флеш Рояль

Тоцка Тала
Детективы:
триллеры
7.11
рейтинг книги
Флеш Рояль

Боярышня Дуняша

Меллер Юлия Викторовна
1. Боярышня
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Боярышня Дуняша

Газлайтер. Том 8

Володин Григорий
8. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 8

Леди для короля. Оборотная сторона короны

Воронцова Александра
3. Королевская охота
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Леди для короля. Оборотная сторона короны

На границе империй. Том 10. Часть 1

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 1

Черный Маг Императора 5

Герда Александр
5. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 5

Невест так много. Дилогия

Завойчинская Милена
Невест так много
Любовные романы:
любовно-фантастические романы
7.62
рейтинг книги
Невест так много. Дилогия

Идеальный мир для Социопата 3

Сапфир Олег
3. Социопат
Фантастика:
боевая фантастика
6.17
рейтинг книги
Идеальный мир для Социопата 3

Повелитель механического легиона. Том VIII

Лисицин Евгений
8. Повелитель механического легиона
Фантастика:
технофэнтези
аниме
фэнтези
5.00
рейтинг книги
Повелитель механического легиона. Том VIII

Наследник павшего дома. Том I

Вайс Александр
1. Расколотый мир
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник павшего дома. Том I

Крещение огнем

Сапковский Анджей
5. Ведьмак
Фантастика:
фэнтези
9.40
рейтинг книги
Крещение огнем

Камень Книга двенадцатая

Минин Станислав
12. Камень
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Камень Книга двенадцатая