Стандарты программирования на С++. 101 правило и рекомендация | страница 116
>// типа T "foo-совместимости", т.е. наличия функции-члена с
>// данным именем, сигнатурой и семантикой
>template
>void Sample1(T t) {
> t.foo(); // foo - точка настройки
> typename T::value_type x; // Еще один пример: создание
>} // точки настройки для поиска
> // типа (обычно создается посредством typedef)
Для реализации первого варианта автор >Sample1
должен выполнить следующие действия.
• Вызвать функцию как член. Просто используйте естественный синтаксис вызова функции-члена.
• Документировать точку настройки. Тип должен обеспечить доступную функцию-член foo, которая может быть вызвана с данными аргументами (в данном случае — без аргументов).
Второй вариант представляет собой использование метода "неявного интерфейса", но с функциями, не являющимися членами, поиск которых выполняется с использованием ADL[3](т.е. ожидается, что данная функция находится в пространстве имен типа, для которого выполняется инстанцирование шаблона). Именно эта ситуация и явилась основной побудительной причиной для введения ADL (см. рекомендацию 57). Ваш шаблон рассчитывает на то, что для используемого типа имеется подходящая функция с заданным именем:
>// Вариант 2: Создание точки настройки путем требования от
>// типа T "fоо-совместимости", т.е. наличия функции, не
>// являющейся членом с данным именем, сигнатурой и
>// семантикой, поиск которой выполняется посредством ADL.
>// (Это единственный вариант, при котором не требуется поиск
>// самого типа T.)
>template
>void Samplе2(T t) {
> foo(t); // foo - точка настройки
> cout << t; // Еще один пример - operator<< с записью в
>} // виде оператора представляет собой такую же
> // точку настройки
Для реализации варианта 2 автор >Samplе2
должен выполнить следующие действия.
• Вызвать функцию с использованием неквалифицированного имени (включая использование естественного синтаксиса в случае операторов) и убедиться, что шаблон не имеет функции-члена с тем же именем. В случае шаблонов очень важно, чтобы вызов функции был не квалифицированным (например, не следует писать >SomeNamespace::foo(t)
) и чтобы у шаблона не было функции-члена с тем же именем, поскольку в обоих этих случаях поиск, зависящий от аргумента, выполняться не будет, что предотвратит поиск имени в пространстве имен, в котором находится тип >T
.
• Документировать точку настройки. Тип должен обеспечить наличие функции, не являющейся членом, которая может быть вызвана с данными аргументами.