Un nome di classe completo fino all'ambito globale è mai richiesto per le definizioni di funzioni membro fuori linea?


14

Questa domanda mi ha fatto domandare se sia mai utile / necessario qualificare completamente i nomi di classe (incluso l'operatore di ambito globale) in una definizione di funzione membro fuori classe.

Da un lato, non l'ho mai visto prima (e la sintassi per farlo correttamente sembra oscura). Dall'altro, la ricerca del nome C ++ è molto semplice, quindi forse esiste un caso angolare.

Domanda:

Esiste mai un caso in cui l'introduzione di una definizione di funzione membro fuori classe
ReturnType (::Fully::Qualified::Class::Name::MemberFunctionName)(...) { ... }
differirebbe da
ReturnType Fully::Qualified::Class::Name::MemberFunctionName(...) { ... }(nessun ::prefisso di ambito globale )?

Si noti che le definizioni delle funzioni membro devono essere inserite in uno spazio dei nomi che racchiude la classe, quindi questo non è un esempio valido.


Molto curioso di ciò che al downvoter non piace questa domanda. Feedback di benvenuto!
Max Langhof,

quando la definizione viene inserita in uno spazio dei nomi diverso dalla dichiarazione? Questo è quello che avevo in mente per il quesiton che colleghi
idclev 463035818

oops, non ho letto l'impronta piccola;)
idclev 463035818

@ formerlyknownas_463035818 Questo è anche ciò che avevo in mente, poi l'ho provato e ho capito che non avrebbe funzionato, quindi ho scritto la domanda (immaginando che anche gli altri si sarebbero chiesti).
Max Langhof,

Risposte:


12

Una direttiva using può Fullyessere ambigua senza qualifica.

namespace Foo {
    struct X {
    };
}

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

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

5

È necessario se uno è un masochista e ama scrivere cose del genere

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

   struct bar {
       void baz();
   };

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

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

Naturalmente si può scrivere il secondo sovraccarico come foo::foo::bar::baznell'ambito globale, ma la domanda era se le due dichiarazioni possono avere o meno un significato diverso. Non consiglierei di scrivere questo codice.


Sì, questa è davvero una risposta valida e non ha nemmeno bisogno di un using. Bello avere diversi casi evidenziati!
Max Langhof,

2

Se viene utilizzata una direttiva using, potrebbe esserci un codice confuso.

Considera il seguente programma dimostrativo

#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;
}

Quindi per leggibilità questo nome qualificato

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

mostra esattamente dove viene dichiarata la funzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.