Czy w przypadku definicji funkcji członka poza linią wymagana jest w pełni kwalifikowana nazwa klasy do zasięgu globalnego?


14

To pytanie sprawiło, że zastanawiałem się, czy kiedykolwiek przydatne / konieczne jest pełne kwalifikowanie nazw klas (w tym operatora zasięgu globalnego) w definicji funkcji członka poza klasą.

Z jednej strony nigdy wcześniej tego nie widziałem (a składnia, aby to zrobić, wydaje się niejasna). Z drugiej strony wyszukiwanie nazw w C ++ jest bardzo nietrywialne, więc może istnieje przypadek narożny.

Pytanie:

Czy kiedykolwiek zdarza się, że wprowadzenie pozaklasowej definicji funkcji członka
ReturnType (::Fully::Qualified::Class::Name::MemberFunctionName)(...) { ... }
różni się od
ReturnType Fully::Qualified::Class::Name::MemberFunctionName(...) { ... }(brak ::prefiksu zasięgu globalnego )?

Należy pamiętać, że definicje funkcji członek musi być wprowadzane do otaczającej przestrzeni nazw klasy, więc to nie jest poprawnym przykładem.


Bardzo ciekawe, co downvoter nie lubi w tym pytaniu. Witamy mile widziane!
Max Langhof,

kiedy definicja jest umieszczona w innym obszarze nazw niż deklaracja? Właśnie to miałem na myśli przy
pytaniu, które łączysz

Ups, nie przeczytałem małego odcisku;)
idclev 463035818,

@ previouslyknownas_463035818 To też miałem na myśli, a potem spróbowałem i zdałem sobie sprawę, że to nie zadziała, więc napisałem pytanie (myśląc, że inni też by się zastanawiali).
Max Langhof,

Odpowiedzi:


12

Użyciu dyrektywą może powodować Fullybyć niejednoznaczne bez kwalifikacji.

namespace Foo {
    struct X {
    };
}

using namespace Foo;
struct X {
    void c();
};

void X::c() { } // ambiguous
void ::X::c() { } // OK

5

Jest to konieczne, jeśli ktoś jest masochistą i lubi pisać takie rzeczy

namespace foo {
    namespace foo {
        struct bar {
            void baz();
        };
    }

   struct bar {
       void baz();
   };

   void foo::bar::baz() {
   }

   void (::foo::bar::baz)() {
   }
} 

Drugie przeciążenie można oczywiście napisać jak foo::foo::bar::bazw zakresie globalnym, ale pytanie brzmiało, czy te dwie deklaracje mogą mieć inne znaczenie. Nie polecałbym pisania takiego kodu.


Tak, to jest rzeczywiście poprawna odpowiedź i nawet nie potrzebuje using. Miło mieć różne przypadki podświetlone!
Max Langhof,

2

Jeśli używana jest dyrektywa używająca, kod może być mylący.

Rozważ następujący program demonstracyjny

#include <iostream>
#include <string>

namespace N1
{
    struct A
    {
        void f() const;
    };      
}

using namespace N1;

void A::f() const { std::cout << "N1::f()\n"; }

struct A
{
    void f() const;
};

void ::A::f() const { std::cout << "::f()\n"; }

int main() 
{
    N1::A().f();
    ::A().f();

    return 0;
}

Więc dla czytelności ta kwalifikowana nazwa

void ::A::f() const { std::cout << "::f()\n"; }

pokazuje dokładnie, gdzie funkcja jest zadeklarowana.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.