видимость функций друзей при создании функторов - PullRequest
1 голос
/ 24 января 2011

См. Код ниже.drive() входит в объем , я могу drive porsche.Однако, если я не раскомментирую объявление drive(), g ++ выдаст очень странный 'диск', который не был объявлен в этой области видимости ошибки при попытке создать функтор.Почему?

#include <functional>

class car {
    friend void drive(const car c);
};

//void drive(const car c);

int main() {

    car porsche;
    drive(porsche);
    std::pointer_to_unary_function<car, void> functor(drive);

    return 0;
}

ОБНОВЛЕНИЕ 1: Я почти удовлетворен ответом относительно ADL, однако я действительно сказал тип аргумента привода, это первый параметр шаблона, этоis car:

std::pointer_to_unary_function<car, void> functor(drive);

ОБНОВЛЕНИЕ 2: Хорошо, вот еще более простой код, нам не нужен функтор и функциональный заголовок:

class car {
    friend void drive(const car c);
};

//void drive(const car c) { }

int main() {
    car porsche;
    drive(porsche);
    void (*f)(const car);
    f = drive;
    return 0;
}

Теперь я понимаю, почему компилятор не может найти drive с ADL.Причина та же, что и выше, но этот код не скрыт шаблоном.

Ответы [ 2 ]

5 голосов
/ 24 января 2011

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

Если эта функция ранее не была объявлена, то объявление friend не делает эту функцию видимой в этой области.

Однако эта функция видима для зависимого от аргумента поиска .

В выражении drive(porsche);, porsche имеет тип car, поэтому используется ADL и можно найти функцию друга.

В выражении drive нет аргументов, поэтому ADL не выполняется. Нет никакого объявления drive видимого, поэтому поиск не удается.

0 голосов
/ 24 января 2011

Поскольку друг не объявляет функцию, а вы пытаетесь вызвать глобальную функцию, которой не существует.

...