7

Rozważmy następujący:Argument dla znajomego funkcjonuje

namespace N { 
    struct A { }; 

    struct B { 
     B() { } 
     B(A const&) { } 
     friend void f(B const&) { } 
    }; 
} 

int main() { 
    f(N::B{}); // ok 
    f(N::A{}); // error 
} 

W pierwszym przypadku sprawa się powiedzie - uważamy przynależne nazw z N::B i znaleźć N::f(B const&). Wspaniały.

Drugi przypadek nie powiedzie się. Czemu? Według [namespace.memdef]:

Jeżeli deklaracja w nielokalnego klasy friend pierwszy deklaruje klasę, funkcja, klasa szablon lub szablon funkcja przyjaciel jest członkiem najbardziej wewnętrznej otaczającej przestrzeni nazw. [...] Jeśli wywoływana jest funkcja przyjaciel lub szablon funkcji , jej nazwa może być znaleziona przez wyszukiwanie nazw, które uwzględnia funkcje z przestrzeni nazw i klas powiązanych z typami argumentów funkcji (3.4.2).

Związane z nazw jest NN::A, z których f jest członkiem, więc dlaczego nie znaleźć przez wyszukiwarkę?

Odpowiedz

8

Dzieje się tak, ponieważ f nie jest zadeklarowany w powiązanej klasie. B jest klasą skojarzoną, gdy argument jest typu B, ale nie jest, gdy argumentem jest typ A.

I zacytować [basic.lookup.argdep]/4, kopalnia nacisk:

Rozważając związanego nazw, odnośnika jest taki sam jak w wyszukiwarce wykonywana, gdy wiąże się przestrzeni nazw stosuje się jako kwalifikator (3.4.3.2) z wyjątkiem:

- Wszelkie dyrektywy użycia w powiązanej przestrzeni nazw są ignorowane.

- Wszelkie funkcje przyjaciel namespace-zakres lub szablony funkcji przyjaciel zadeklarowane w powiązanych klas są widoczne w ich odpowiednich nazw, nawet jeśli nie są one widoczne podczas zwykłego odnośnika (11,3).

- Wszystkie nazwy z wyjątkiem nazw funkcji (prawdopodobnie przeciążonych) i szablonów funkcji są ignorowane.

Powiązane problemy