#include <iostream>
#include <string>
class X {};
namespace N
{
std::string to_string(X)
{
return "foo";
}
void foo()
{
//using std::to_string; // will break the build if uncommented...
//using N::to_string; // ...unless this is uncommented as well
std::cout << to_string(X()) << std::endl;
}
}
int main()
{
N::foo();
return 0;
}
Либо я наткнулся на одну из многих C++ arcana, которую я не осваиваю, или мне не хватает чего-то очевидного здесь.Как декларация использования уменьшает имена, доступные для поиска без ADL?
Как может using std::to_string
, по-видимому, уменьшить набор имен, доступных во время неквалифицированного поиска, только для тех, которые доступны через ADL? Хотя я могу догадаться, проблема может заключаться в том, что to_string(X)
объявлен в другом пространстве имен, чем X
. Не могу не заметить, что без using std::to_string
, N::to_string(X)
просто доступен для N::foo()
с помощью «обычных», интуитивно понятных правил поиска, к которым я привык.
Справедливо, спасибо. – gd1
Я заметил, однако, что аналогия с объявлением 'int to_string' не * всегда * выполняется: на самом деле' using std :: to_string' не скрывает функцию 'to_string (X)', объявленную в 'X'' пространство имен, которое должно быть найдено из ADL, тогда как 'int to_string' вызовет ошибку компилятора. Аналогия выполняется, если я объявляю 'std :: string to_string (int)', например, в 'foo()'. – gd1
Да, это другой случай. ADL заставит компилятор рассматривать функцию из связанных с ними пространств имен, даже если это не будет видно иначе. Но это не относится к коду в вопросе, так как «X» находится за пределами пространства имен. –