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

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

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

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

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


person M3taSpl0it    schedule 06.02.2013    source источник
comment
Удар ... опубликованный ответ не отвечает на вопрос, почему ADL не находит bar в этом коде, вместо этого он говорит о функциях друзей   -  person M.M    schedule 08.04.2016


Ответы (1)


Вероятно, он имел в виду следующее:

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

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

Но тогда технически bar() не внутри foo. Он по-прежнему во внутреннем пространстве имен foo.

--

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

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

Лучшим примером является функция 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

Or,

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

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

person Nawaz    schedule 06.02.2013
comment
Но почему ADL не рассматривает статическую функцию внутри класса, а ADL действительно учитывает объем самого класса, это не так? - person M3taSpl0it; 06.02.2013
comment
@ M3taSpl0it: Нет. Как я уже сказал, он все еще находится во внутреннем пространстве имен foo. Функция друга оказывается внутри класса. Имя, фактически объявленное в охватывающей области пространства имен. - person Nawaz; 06.02.2013
comment
Спасибо за подтверждение, я ценю ваш ответ, можете ли вы сделать резервную копию своего утверждения с поддержкой утверждений, указанных в стандарте C ++, противоречащих моему примеру? . Спасибо - person M3taSpl0it; 06.02.2013
comment
@ M3taSpl0it: Пожалуйста, прочтите раздел, в котором говорится о friend и ADL (я немного занят, поэтому сам не могу зациклить). А также посмотрите следующий пример в моем ответе (который я добавил сейчас). - person Nawaz; 06.02.2013
comment
@ M3taSpl0it: P.S: ваш большой (O) ответ на редактирование неэффективен: P .. значит? - person Nawaz; 06.02.2013