Разве ADL не ищет статические функции-члены?

Это дополнительный вопрос от Поиск, зависящий от аргументов, также ищет только пространства имен или классы? , В котором @David Rodríguez сказал: «ADL будет искать во вложенном пространстве имен типа, а также внутри сам тип «. Возможно, я неправильно понял, что он пытался сказать, но я пробовал этот пример:

struct foo{
static void bar(foo* z){}
};

int main(){
foo* z;
bar(z);
}

Он не компилируется, выдает ошибку «bar» не был объявлен в этой области ». Это тот случай, когда ADL не рассматривает статическую функцию-член? Я имею в виду в примере связанный класс foo так почему бы ADL не заглянуть внутрь класса? , Может кто-нибудь, пожалуйста, упростить правила здесь?

7

Решение

Он, вероятно, имел в виду это:

struct foo{
friend void bar(foo* z){}    //not static, its friend now
};

foo* z;
bar(z); //fine now

Но тогда технически bar() не является внутри foo, это еще во вложенном пространстве имен foo,

РЕДАКТИРОВАТЬ:

Он действительно имел в виду friend, как он сказал (выделение мое):

Лучший пример друг функция, которая определяется внутри тип

И его пример иллюстрирует дальше. Вероятно, вам нужно читать «определено внутри», а не только «внутри».

Слово «определено» это все, что имеет значение, потому что оно похоже функции название bar вводится в рамки класса, но на самом деле, имя bar вводится во вложенное пространство имен foo (см. §3.3.1 / 3-4 и §11.3 / 6).

Вот лучший пример:

namespace Demo
{
struct foo
{
friend void bar(foo* z){}
};
}

foo *z;
bar(z); //foo (type of z) is inside Demo, so is bar
//(even though bar is defined inside foo!)

bar(NULL);    //error - NULL doesn't help ADL.
bar(nullptr); //error - nullptr doesn't help ADL.

bar(static<foo*>(NULL)); //ok - ADL

Обратите внимание, что имя barдаже если он введен в пространство имен Demo, скрыт, и поэтому не могу использоваться извне, используя обычный поиск по имени:

using namespace Demo; //brings ALL (visible) names from Demo to current scope

bar(NULL); //STILL error - means bar is invisible

Или же,

Demo::bar(NULL);       //error - not found
Demo::foo::bar(NULL);  //error - not found

Надеюсь, это поможет.

6

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

Других решений пока нет …