Уловка Бартона – Накмана - Barton–Nackman trick

Уловка Бартона – Накмана это термин, введенный комитетом по стандартизации C ++ (ISO / IEC JTC1 / SC22 WG21) для обозначения идиома представленный Джоном Бартоном и Ли Накманом как Ограниченное расширение шаблона.[1]

Идиома

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

// Шаблон класса для выражения интерфейса сравнения равенства.шаблон<typename Т> учебный класс equal_comparable {    друг bool оператор==(Т const &а, Т const &б) { возвращаться  а.равно(б); }    друг bool оператор!=(Т const &а, Т const &б) { возвращаться !а.равно(б); }}; // Класс value_type хочет иметь == и! =, Поэтому он является производным от // равный_сопарабельному самому себе в качестве аргумента (который является CRTP).учебный класс тип ценности : частный equal_comparable<тип ценности> {  общественный:    bool равно(тип ценности const& rhs) const; // быть определенным};

Когда шаблон класса вроде equal_comparable создается экземпляр, определения друзей в классе производят не шаблонный (и не являющиеся членами) функции (в данном случае операторные функции). В то время, когда эта идиома была введена (1994 г.), язык C ++ не определял частичное упорядочение для перегруженных шаблонов функций, и в результате перегрузка шаблонов функций часто приводила к двусмысленностям. Например, попытка получить общее определение для оператор == так как

шаблон<typename Т>bool оператор==(Т const &а, Т const &б) {    /* ... */}

было бы несовместимо с другим определением, например

шаблон<typename Т>bool оператор==(Множество<Т> const &а, Множество<Т> const &б) {    /* ... */}

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

Иногда этот термин ошибочно используется для обозначения Любопытно повторяющийся шаблон шаблона (CRTP). Как объяснялось выше, трюк Бартона – Накмана - это отдельная идиома (основанная на CRTP).

Как это устроено

Когда компилятор встречает выражение

v1 == v2

куда v1 и v2 относятся к типу тип ценности, он пытается поиск, зависящий от аргументов (ADL) для оператор ==. Этот поиск включает рассмотрение дружественных функций, объявленных в тип ценности и его базовые классы. (Обратите внимание, что если тип ценности были неполным экземпляром шаблона, ADL запускал бы его полное создание.)

Уловка Бартона – Накмана изначально основывалась не на ADL, а на функции C ++, называемой «инъекция имени друга», в которой внутриклассовое объявление функции друга делало имя функции видимым в непосредственно окружающей области пространства имен (возможно, в глобальной области) . При исследовании возможности удаления инъекции имени друга из языка программирования C ++ было обнаружено, что идиома Бартона и Накмана является единственным разумным применением этого правила языка. В конце концов, правила поиска по аргументам были скорректированы.[2] заменить инъекцию имени друга менее радикальным механизмом, описанным выше, который сохранил действенность техники Бартона и Накмана. Стоит отметить, что вследствие этого изменения выражение

:: оператор == (v1, v2)

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

Смотрите также

Рекомендации

  1. ^ Бартон, Джон Дж .; Накман, Ли Р. (1994). Научный и инженерный C ++: введение с передовыми методами и примерами. Эддисон-Уэсли. ISBN  0-201-53393-6.
  2. ^ «Альтернатива внедрению имени из шаблонов» (PDF). 26 сентября 1995 г.. Получено 12 апреля 2005.

дальнейшее чтение