Ответ 1
Это не удается из-за поиска двухфазного имени в С++.
В первой фазе, когда шаблон сначала анализируется, задолго до его создания, компилятор анализирует шаблон и ищет все не зависящие имена. S::P
- это необязательное имя, поэтому компилятор пытается найти его, но он не работает, потому что он является конфиденциальным.
В фазе 2, когда экземпляр шаблона создается, компилятор будет искать любые зависимые имена, которые могут варьироваться от шаблона к шаблону.
Clang довольно строго соответствует поиску двухфазных имен. Тем не менее, MSVC имеет модель синтаксического анализа шаблонов, которая задерживает почти каждый поиск времени создания, что является частью фазы 2. Эта задержка - это то, почему ваш пример будет скомпилирован с MSVC (который не соответствует требованиям), а не в clang. Вот ссылка на дополнительную информацию:
Страшный двухфазный поиск имени
Кроме того, здесь представлены разделы из стандарта С++, где описывается двухфазный поиск.
14.6.8:
При поиске объявления имени, используемого в шаблоне определение, обычные правила поиска (3.4.1, 3.4.2) используются для не зависящие от имени имена. Поиск имен, зависящих от шаблона параметры откладываются до тех пор, пока не будет известен фактический аргумент шаблона.
14.6.9:
Если имя не зависит от параметра шаблона (как определено в 14.6.2) объявление (или набор деклараций) для этого имени должно быть в области действия в точке, где имя отображается в шаблоне определение; имя связано с объявлением (или декларациями) найденные в этот момент, и это обязательство не зависит от объявлений которые видны в момент создания экземпляра.
Затем применяется часть поиска по имени 3.4:
Правила доступа (раздел 11) рассматриваются только после поиска имени и (если применимо). Только после поиска имени, разрешения перегрузки функции (если применимо) и проверка доступа прошла успешно, это атрибуты, введенные имена имен, используемые далее в обработке выражений (раздел 5).
Из этого ясно видно, что ваша программа плохо сформирована. Единственное, что стандартное состояние следует отложить до момента создания, это поиск зависимого имени. Не зависящие имена проходят обычный поиск имен, который включает в себя правила доступа.