Неоднозначная ссылка на пространство имен во встроенном пространстве имен

Предположим, следующий код:

namespace test
{
namespace detail
{
}

inline namespace v1
{
namespace detail
{
void foo()
{
}
}
}
}

int main()
{
test::detail::foo();
}

Как мы можем видеть, этот код компилируется с Clang; не с GCC, однако — GCC жалуется, что ссылка на namespace detail неоднозначно:

main.cpp:20:11: error: reference to 'detail' is ambiguous
test::detail::foo();
^
main.cpp:4:5: note: candidates are: namespace test::detail { }
{
^
main.cpp:10:9: note:                 namespace test::v1::detail { }
{
^

Какой компилятор делает правильную вещь здесь?

15

Решение

GCC правильно:

Члены встроенного пространства имен могут использоваться в большинстве случаев так, как если бы они были членами вложенного пространства имен. В частности, внутреннее пространство имен и включающее его пространство имен добавляются к набору связанных пространств имен, используемых в зависимом от аргумента поиске (3.4.2), когда одно из них есть, и с помощью директивы который именует пространство имен, неявно вставляется в окружающее пространство имен что касается безымянного пространства имен (7.3.1.1). Кроме того, каждый член встроенного пространства имен может впоследствии быть явно создан (14.7.2) или явно специализирован (14.7.3), как если бы он был членом окружающего пространства имен. В заключение, поиск имени во вложенном пространстве имен с помощью явной квалификации (3.4.3.2) будет включать членов встроенного пространства имен, введенного с помощью директивы даже если есть объявления этого имени во вложенном пространстве имен.

(Это в 7.3.1 / 8 в старой нумерации n3337)

Я верю, что вы видите Ошибка лягушки # 10361.

13

Другие решения

GCC правильно.

N3797 утверждает, что

и директива об использовании (
7.3.4) что имена встроенного пространства имен неявно вставляются в окружающее пространство имен, как и для безымянного пространства имен (
7.3.1.1).

Таким образом, test::detail не то же самое пространство имен, что и test::v1::detailтак что поиск test::detail неоднозначно. Стандарт исключительно ясно, что поиск test::detail должны включать test::v1::detailв этом разделе есть много цитат, подтверждающих это, но ничего не говорится о том, что они должны рассматриваться как одно и то же пространство имен.

Возможно, я бы сказал, что поведение Clang лучше, но GCC правильно.

5

По вопросам рекламы [email protected]