При разрешении имен, зависящих от шаблона, не должно быть объявлений без привязки?

В стандарте c ++ [temp.point] написано:

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

Затем в [temp.dep.candidate]:

Для части поиска с использованием связанных пространств имен ([basic.lookup.argdep]) обнаруживаются только объявления функций, найденные либо в контексте определения шаблона, либо в контексте создания экземпляра шаблона .

Означает ли это, что следующий код должен завершиться ошибкой:

namespace A{
    struct S{};
}

template<class T>
void g(T a){
    f(a); //f will be found by argument dependent lookup
}

namespace A{
    static void f(S); //but f doesn't have external linkage
}

void test(A::S i){
    g(i);
}
//point of instantiation of g
//A::f(S) doesn't have external linkage 
//=> so it's not in the instantiation context of template g ??

Этот код действительно компилируется, так что же означает этот стандартный абзац?


person Oliv    schedule 22.07.2018    source источник
comment
Я был уверен в своем ответе, пока не прочитал дальше temp.dep.candidate-1.2. IIUC, значит, вы правы. И A::f не должно быть найдено. Какие компиляторы пробовали?   -  person StoryTeller - Unslander Monica    schedule 22.07.2018
comment
@StoryTeller Я пробовал gcc и clang: обозреватель компилятора   -  person Oliv    schedule 22.07.2018
comment
@StoryTeller Итак, я включаю этот абзац в вопрос. Тем не менее, ответ, который вы удалили, был умным, возможно, это и было целью этого абзаца.   -  person Oliv    schedule 22.07.2018
comment
Может, так и было. Но и этот абзац довольно ясен. Я думаю, что Clang и GCC просто возвращаются к тому, что проблема нарушения является плохо сформированным отчетом о недоставке. Я больше не уверен :)   -  person StoryTeller - Unslander Monica    schedule 22.07.2018
comment
@StoryTeller Какие требования к отчету о недоставке могут применяться здесь? В цитируемых абзацах не говорится об отчете о недоставке, и невозможность найти какие-либо функции-кандидаты / наиболее жизнеспособную функцию обычно требует диагностики.   -  person aschepler    schedule 22.07.2018
comment
@aschepler - отчет о недоставке, описанный в следующих (не показанных здесь) абзацах [temp.point]. Если экземпляры шаблонов будут иметь разное значение в разных TU, это плохо сформированный отчет о недоставке. И я думаю, что это то, что Clang и GCC (ошибочно) реализуют здесь, вместо того, чтобы диагностировать отсутствующего кандидата. Я знаю, что это не отчет о недоставке, я обратил внимание Олив на второй абзац.   -  person StoryTeller - Unslander Monica    schedule 22.07.2018


Ответы (1)


Это дефект стандарта. Первоначально рассмотрено в основном вопросе 561, где комитет решил, что

Примечания с встречи в апреле 2006 г.

Группа согласилась [...] с тем, что функции внутренней связи должны быть найдены с помощью поиска (хотя они могут привести к ошибкам, если выбраны путем разрешения перегрузки).

К сожалению, соответствующего исправления было недостаточно, как описано в основной проблеме 1258:

C ++ 11 расширил правила поиска для вызовов зависимых функций (17.7.4.2 [temp.dep.candidate] абзац 1, пункт 2), чтобы включить функции с внутренней связью; ранее рассматривались только функции с внешней связью. Однако в пункте 6 17.7.4.1 [temp.point] по-прежнему говорится:

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

Предположительно эта формулировка не была учтена и должна быть согласована с новой спецификацией.

То есть предыдущая формулировка вашего второго цитируемого абзаца была

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

.. который был изменен для C ++ 11, но это изменение пропустило вашу первую цитату, что сделало его бессмысленным. Цель состоит в том, чтобы функции с внутренней связью не различались.

person Columbo    schedule 22.07.2018
comment
Рад это слышать, мне было интересно, нужно ли мне включать заголовки библиотек после объявления статических функций в файлах реализации! - person Oliv; 22.07.2018