in-class explicit specializations


Телега лежала уже третьи сутки. Иногда оттуда доносились сдавленные хрипы push-уведомлений, но кружащие сверху стервятники прозрачно намекали на вероятный исход. Завтра мы узнаем, не зря ли мы все перешли на Макс.
Я с сомнением посмотрел на поле ввода текста национального мессенджера. Вроде как в ICQ вернулся. Нет! Не время ныть, вначале все должны узнать как GCC беспардонно попирает стандарт!
Есть такая штука как CWG, Core Working Group. Рассматривает эта группа всякие интересные ситуации, вроде разнотыки в стандарте. Их, слава богу, хватает.
Например, некто Faisal Vali еще в 2008 году заметил серьезный недочет во внутриклассовой явной специализации. Особо не мудрствуя, документ так и назвали CWG 727: In-class explicit specializations.
Дело в том, что стандарт в пункте 13.9.4 [temp.expl.spec] втором параграфе требует, чтоб явные специализации шаблонных членов были в пространстве имен вне класса, а не внутри. Это ограничение не применяется для частичных специализаций шаблонных членов класса:
𝚜𝚝𝚛𝚞𝚌𝚝 𝙰 {
𝚝𝚎𝚖𝚙𝚕𝚊𝚝𝚎<𝚌𝚕𝚊𝚜𝚜 𝚃> 𝚜𝚝𝚛𝚞𝚌𝚝 𝙱;
𝚝𝚎𝚖𝚙𝚕𝚊𝚝𝚎 <𝚌𝚕𝚊𝚜𝚜 𝚃> 𝚜𝚝𝚛𝚞𝚌𝚝 𝙱<𝚃*> { }; // Нормально
𝚝𝚎𝚖𝚙𝚕𝚊𝚝𝚎 <> 𝚜𝚝𝚛𝚞𝚌𝚝 𝙱<𝚒𝚗𝚝*> { }; // Так нельзя
};
Непоследовательно это как-то беспричинно-несправедливо.
Действительно, сказали разработчики компиляторов и примерно лет через десять починили это.
Во-первых, на уровне стандарта. В стихе втором раздела 14.7.3 Explicit specialization [temp.expl.spec] раньше было:

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

А если посмотреть свежие версии стандарта, то уже в третьем параграфе обнаруживается существенное послабление.

Явная специализация может быть объявлена в любой области, где объявляется базовый шаблон.

Это относится и к методам класса:
𝚜𝚝𝚛𝚞𝚌𝚝 𝙰 {
𝚝𝚎𝚖𝚊𝚙𝚕𝚊𝚝𝚎 <𝚌𝚕𝚊𝚜𝚜 𝚃>
𝚟𝚘𝚒𝚍 𝚖𝚎𝚝𝚑() {}
𝚝𝚎𝚖𝚙𝚕𝚊𝚝𝚎 <>
𝚟𝚘𝚒𝚍 𝚖𝚎𝚝𝚑<𝚒𝚗𝚝>() 𝚌𝚘𝚗𝚜𝚝 {}
};
Во-вторых, разработчики подправили компиляторы. Однако не все, у GCC, как всегда, есть особое мнение на этот счет.
Закономерным итогом строптивости стал заведенный в 2018 году неким songyuanyao баг 85282, что напрямую связан с исправлением cwg727.
Пишет он очевидные вещи, что не выполнены постановления ЦК КПСС по смягчению правил явной специализации.
Багу этому много лет, и он еще не решен. GCC до сих пор нарушает стандарт и запрещает нам явную специализацию внутри класса.
Это может дать очень интересный эффект в самый неожиданный момент.
Просмотры: 25
Открыть в MAX Сообщить о неточности

Репосты публикации

Публикация канала

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти