Ответ 1
Или это просто ошибка компилятора?
Это. Как упоминалось в @T.C., CWG # 577 имеет значение:
[...] там была выражена обеспокоенность по поводу обработки шаблонов функций и функции-члены шаблонов классов, если было изменено правило С++: для параметра шаблона
T
, будет функция, принимающая один параметр типаT
становятся непараметрической функцией, если она была создана с помощьюT = void
Это обоснованная жалоба, но, к сожалению, для вас, функции-члены/функции-члены-функции и идентификаторы типов были одинаково затронуты разрешением:
Список параметров, состоящий из одного неназванного параметра не зависящего типа
void
, эквивалентен списку пустых параметров.
таким образом оба ваши фрагменты плохо сформированы, поскольку тип параметра действительно зависит.
Является ли это правильной реализацией, если нет, как бы она выглядела?
Нет правильной реализации. Если вам нужен тип функции с пустым списком параметров, вам нужно указать, что независимо от параметров шаблона.
Так почему же код выше компилируется и работает, как я и ожидал?
Мое лучшее предположение: VС++ выполняет замену void_template_alias_t<T>
после того, как убедиться, что тип параметра не является зависимым типом "cv void
", но перед тем, как преобразовать "void
→ empty list". Однако часто трудно понять, как VС++ (или любой компилятор, если на то пошло) думает внутренне.