На cppitertools шла дискуссия о новейшей версии MSVC (15.7), заявляющей, что она полностью соответствует стандартам, что привело меня сюда.

Следующий код не может быть скомпилирован под MSVC по одной причине: U в строках 4 и 5 - это другое имя, чем T в строках 10 и 11, поэтому результат условия static_assert в строке 19 ложный. (Обратите внимание, что я не использую здесь std::declval для простоты).

Не верите мне? Вот он на Godbolt, и вот тот же код с gcc, и тот же код снова с лязгом. (Обратите внимание, что у Godbolt нет последней версии MSVC, но я протестировал все это с MSVC 15.7)

То же самое, только U заменено на T в строках 4 и 5 компилируется нормально.

Вы можете подумать: Может быть, в T есть что-то особенное, благодаря чему эта работа работает. Это не так, он работает независимо от имени, пока оно совпадает. Вот тот же код с Apple вместо T.

Становится еще более странным. Я случайно скомпилировал то, чего не хотел, и теперь запутался еще больше.

Псевдоним типа может каким-то образом видеть T typename, хотя это невозможно (godbolt):

Работает даже при использовании template <typename>. Работает при шаблоне на int! Он может видеть T HasFunc!

Однако, чтобы func_type работал вне шаблона, мне все равно нужно использовать T в качестве параметра шаблона, иначе что-то вроде tests::func_type<A> не сработает.

Проблема, кажется, не очень хорошо обобщается. Например, это использование в функции отлично работает:

Я сообщил об ошибке, посмотрим, что будет.

Я потерялся. Спокойной ночи всем.