Clang vs MSVC: обработка прототипов шаблонных функций - PullRequest
11 голосов
/ 16 февраля 2012

Ниже приведен фрагмент тестового кода, и я сравниваю результат компиляции с MSVC и Clang соответственно.Вывод каждого компилятора показан ниже.MSVC делает вид, что объявление о неиспользованном шаблоне даже не существует.Clang выдает ошибку.Вопрос в том, какой компилятор является наиболее стандартным здесь совместимым?

Я видел устаревший производственный код, который основан на поведении MSVC, и я не уверен, можно ли продолжать полагаться на него.1006 *

E:\clangbuild\bin\Release>cl /c /nologo test.cpp
test.cpp

Выдает ошибку в Clang:

E:\clangbuild\bin\Release>clang++ test.cpp
test.cpp:9:4: error: 'P' is a private member of 'S'
S::P Bat(T);
   ^
test.cpp:5:9: note: implicitly declared private here
struct P {};
        ^
1 error generated.

Ответы [ 2 ]

4 голосов
/ 16 февраля 2012

Сбой из-за двухфазного поиска имени в C ++.

На первом этапе, когда шаблон анализируется изначально, задолго до его создания, компилятор анализирует шаблон и ищет всезависимые имена.S::P - это независимое имя, поэтому компилятор пытается его найти, но терпит неудачу, потому что оно закрытое.

На этапе 2, когда создается экземпляр шаблона, компилятор будет искать любые зависимые имена, которые могут варьироваться от шаблона к шаблону.

Clang довольно строго соответствует поиску двухфазного имени.Тем не менее, MSVC имеет модель синтаксического анализа шаблонов, которая задерживает почти каждый поиск на время создания экземпляра, которое является частью фазы 2. Эта задержка является причиной того, что ваш пример будет компилироваться с MSVC (который не соответствует), а не в clang.Вот ссылка с дополнительной информацией:

Поиск двухфазного имени с ужасом

Кроме того, здесь приведены разделы из стандарта C ++, где он описывает двухфазныйlookup.

14.6.8:

При поиске объявления имени, используемого в определении шаблона, используются обычные правила поиска (3.4.1, 3.4.2)для независимых имен.Поиск имен, зависящих от параметров шаблона, откладывается до тех пор, пока фактический аргумент шаблона не станет известен.

14.6.9:

Если имя не зависит от шаблона-параметр (как определено в 14.6.2), объявление (или набор объявлений) для этого имени должно находиться в области видимости в точке, где имя появляется в определении шаблона;имя привязано к объявлению (или объявлениям), найденному в этой точке, и на эту привязку не влияют объявления, видимые в момент создания экземпляра.

Тогда часть 3.4 поиска имени, применимая кВы:

Правила доступа (пункт 11) рассматриваются только после успешного поиска имени и разрешения перегрузки функции (если применимо).Только после поиска имени, разрешения перегрузки функции (если применимо) и проверки доступа успешно выполняются атрибуты, введенные объявлением имени, которые используются в дальнейшем при обработке выражений (пункт 5).

Его прочесть при чтении этих частейчто ваша программа плохо сформирована.Стандарт утверждает, что единственное, что следует отложить до момента создания экземпляра, - это поиск зависимого имени.Независимые имена проходят обычный поиск имен, который включает в себя правила доступа.

3 голосов
/ 16 февраля 2012

Компилятору действительно требуется проверять любой некорректный синтаксис необоснованных объявлений шаблонов. Любая дополнительная семантическая оценка должна выполняться только при создании экземпляра функции шаблона.

Поскольку S :: P действительно является типом, который является допустимым для возврата из функции, они оба одинаково совместимы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...