Re[4]: Проблема с Dependent Name Lookup
От: Николай Ивченков  
Дата: 30.09.09 09:44
Оценка:
jazzer:

J>А так — это просто шаблонная функция, у которой параметр шаблона не фигурирует в аргументах (но используется где-то внутри, например), это совершенно валидно.


Это корректно только если в A действительно присутствует такая функция:

struct B;

namespace A {
    template <typename T>
        void foo(B *) {}
}

struct B {
    template<typename T>
        friend void A::foo(B *);
};

Если же рассматривать

namespace A
{
    template <typename T>
        void foo(T*) {}
}

struct B
{
    template<typename T>
        friend void A::foo(B *);
};

то здесь функции разные и такая программа будет ill-formed — см. 8.3/1:

When the declarator-id is qualified, the declaration shall refer to a previously declared member of the class or namespace to which the qualifier refers, and the member shall not have been introduced by a using-declaration in the scope of the class or namespace nominated by the nested-name-specifier of the declarator-id.

J>Ну и эта функция, я думаю, инжектируется в объемлющее В пространство имен.

Такого точно нету. Friend-объявление может добавить новый член в пространство имён только если сущность, объявляемая другом, обозначена неквалифицированным именем, однако новое имя в пространство имён этом не вводится. См. 7.3.1.2/3:

If a friend declaration in a non-local class first declares a class or function [footnote 83: this implies that the name of the class or function is unqualified] the friend class or function is a member of the innermost enclosing namespace. The name of the friend is not found by simple name lookup until a matching declaration is provided in that namespace scope (either before or after the class declaration granting friendship). If a friend function is called, its name may be found by the name lookup that considers functions from namespaces and classes associated with the types of the function arguments (3.4.2).

(случай, когда friend-объявление находится в локальном классе, описан в 11.4/9).

struct X
{
    friend void f(X) {}
    friend void f(int) {}
};

int main()
{
    f(X()); // well-formed: f не находится через unqualified lookup, но находится через ADL
    f(0);   // ill-formed: f не находится ни через unqualified lookup, ни через ADL
}
Re[5]: Проблема с Dependent Name Lookup
От: jazzer Россия Skype: enerjazzer
Дата: 30.09.09 09:48
Оценка:
Здравствуйте, Николай Ивченков, Вы писали:

НИ>Это корректно только если в A действительно присутствует такая функция:

НИ>...
НИ>то здесь функции разные и такая программа будет ill-formed — см. 8.3/1:

Ну, значит, это баг GCC.
Я не проверял на более новой версии, версия 3.4.6 — довольно-таки старая
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.