Будет ли больше не разрешена специализация шаблонов функций в std для программно-определенных типов в C ++ 20? - PullRequest
0 голосов
/ 11 октября 2018

Цитата из cppreference.com :

Добавление специализаций шаблона

Разрешено добавлять специализации шаблона для любой стандартной библиотеки | class (начиная с C ++ 20) | шаблон к пространству имен std, только если объявление зависит хотя бы от одного определенного программным типа и специализация удовлетворяет всем требованиям для исходного шаблона, за исключением случаев, когда такие специализациизапрещено.

Означает ли это, что начиная с C ++ 20 добавление специализаций шаблонов функций в пространство имен std для пользовательских типов больше не будет разрешено?Если так, это означает, что многие части существующего кода могут сломаться, не так ли?(Мне кажется, это своего рода «радикальное» изменение.) Более того, оно внедрит в такие коды неопределенное поведение, которое не вызовет ошибок компиляции (надеюсь, предупреждения будут).

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

В нынешнем виде это определенно выглядит так.Ранее [namespace.std] содержал

Программа может добавить специализацию шаблона для любого стандартного шаблона библиотеки в пространство имен std, только если объявление зависит от пользовательского типа испециализация соответствует требованиям стандартной библиотеки для исходного шаблона и не запрещена явно.

В то время как текущий черновик гласит:

Если явно не запрещено,программа может добавить специализацию шаблона для любого стандартного шаблона класса библиотеки в пространство имен std при условии, что (a) добавленное объявление зависит хотя бы от одного определенного программным типа и (b) специализация соответствует требованиям стандартной библиотеки дляоригинальный шаблон.

выделение минное

И похоже на бумагу Не специализируй шаблоны стандартных функций! от Walter EБраун несет ответственность за это.В нем он приводит ряд причин, по которым это должно быть изменено, таких как:

  • Херб Саттер: «Специализации не участвуют в перегрузке.[...] Если вы хотите настроить базовый шаблон функции и хотите, чтобы эта настройка участвовала в разрешении перегрузки (или всегда использовалась в случае точного соответствия), сделайте ее простой старой функцией, а не специализацией.И, если вы предоставляете перегрузки, избегайте также предоставления специализаций ».
  • Дэвид Абрахамс:« неправильно использовать специализацию шаблонов функций [потому что] он плохо взаимодействует с перегрузками.[...] Например, если вы специализируете обычный std::swap для std::vector<mytype>&, ваша специализация не будет выбрана вместо стандартного вектора swap, потому что специализации не учитываются при разрешении перегрузки. ”
  • Говард Хиннант: «Этот вопрос уже давно решен.,,,Не обращайте внимания на мнение / ответ эксперта Дейва в этой области на свой страх и риск. »
  • Эрик Ниблер:« [из-за] решительного способа C ++ разрешает вызовы функций в шаблонах.,,, [w] мы делаем неквалифицированный вызов swap, чтобы найти перегрузку, которая может быть определена в [...] связанных пространствах имен [...], и мы делаем using std::swap так, чтобы навероятность того, что такой перегрузки нет, мы найдем версию по умолчанию, определенную в пространстве имен std. »
  • Стандарт кодирования High Integrity C ++:« Разрешение перегрузки не учитывает явные специализации шаблонов функций.Только после выбора разрешения перегрузки шаблон функции будет рассматриваться для любых явных специализаций. ”
0 голосов
/ 11 октября 2018

Не совсем так радикально.Это изменение основано на этой статье Уолтера Э. Брауна .Документ достаточно глубоко обоснован, но в конечном итоге сводится к следующему:

  1. Специализация шаблонов функций довольно скудна как точка настройки.Перегрузка и ADL намного лучше в этом отношении.В статье также обсуждаются и другие точки настройки.
  2. Стандартная библиотека уже не слишком полагается на эту плохую точку настройки.
  3. Изменение формулировки, которое вводится в действие, фактически позволяет добавлятьвсе объявления в пространстве имен std (не только специализации), где это явно разрешено.Так что теперь есть лучше точек настройки.

Учитывая # 1 и # 2, вряд ли существующий код сломается.Или, по крайней мере, недостаточно, чтобы это стало серьезной проблемой.Код, который использовал auto и register, также «ломался» в прошлом, но это незначительное количество кода C ++ не останавливало прогресс.

...