2014-09-30 23 views
9

w C++ Przestrzeń nazw anonimowy odpowiada:Co zrobić, jeśli potrzebuję anonimowego obszaru nazw w nagłówku?

namespace $$$$ { 
    //something 
} 
using namespace $$$$; 

Gdzie $$$$ jest pewnego rodzaju unikalnego identyfikatora. Anonimowy obszar nazw jest wtedy użyteczny dla kodu, który nie powinien być widoczny poza jednostką kompilacji.

Jak na razie dobrze, jednak ostatnio zacząłem pisać kod z szablonami, taki kod musi znajdować się w nagłówkach, więc używanie anonimowych przestrzeni nazw nie ma większego sensu, ponieważ samo włączenie nagłówka niweczy efekt izolacji.

To pytanie brzmi, jaki jest sugerowany sposób w tym przypadku? Zacząłem używać nazwanej przestrzeni nazw o nazwie Prywatne. Nie przeszkadza to nikomu, kto chce używać identyfikatorów w środku, ale przynajmniej zmniejsza konflikt nazwy do id "Prywatne".

Czy są lepsze sposoby? Propozycje?

+5

AFAIK to wszystko można zrobić, biblioteki szablonów często używać nazw takich jak 'detail' dla tego samego celu. – user657267

+0

Idealnie cały kod powinien znajdować się w jakiejś przestrzeni nazw. Umieść szablony w jakiejś przestrzeni nazw o nazwie Utility lub Alpha lub MyWork lub czymś podobnym. I umieść tam również funkcje pomocy. –

+0

Dzięki user657267; to było potwierdzenie, którego szukałem. Bałem się, że brakuje mi tego, co oczywiste. –

Odpowiedz

3

Trzymaj się swojego Privatenamespace (lub użyj bardziej popularnego detail). Pamiętaj, że główną ideą mechanizmów dostępu C++ jest utrudnianie ich niewłaściwego użycia. Chroń się przed wypadkami, a nie złośliwymi atakami.

4

Jeśli jesteś zdesperowany z powodu tej izolacji, dlaczego nie stary dobry plik - static? Został undeprecated:

template <typename T> 
static void foo() 
{} 

int main() 
{ 
    foo<char>(); 
} 

Potem znowu, jeśli trzeba tylko foo w jedną jednostkę tłumaczeniową, wtedy prawdopodobnie jesteś w tym to tylko w nagłówku obrębie tej jednostki translacji, i to nie ma znaczenia, czy jest to w ogóle "w nagłówku". Więc po prostu nie dołączaj szablonów do innych jednostek tłumaczeniowych i już osiągnąłeś swój cel izolacji.

Aby naprawdę izolacja gwarancja wszystkie możliwych dawałaby (czyli w tym te, które zostały utworzone w tym TU), użyj static jak wyżej lub po prostu udokumentować swój zamiar za pomocą detail nazw.

+0

+1: Szablony muszą znajdować się tylko w nagłówku, jeśli chcesz używać ich w wielu jednostkach tłumaczeniowych. –

0

Najczęstszym sposobem ukrycia implementacji kodu szablonu w nagłówku jest umieszczenie implementacji w przestrzeni nazw o nazwie detail.

Na przykład:

namespace cpputil { // my c++ utility library namespace 

    namespace detail { // implementation details of this libraries headers go here 

    // a functor private to the library 
    template<class T> 
    struct private_functor { 
     private_functor(const T& t) : _t(t) {} 
     void write(std::ostream& os) const { _t.write(os); } 
    private: 
     const T& _t; 
    }; 

    // an extension to std::ostream::operator<< 
    template<class T> 
    std::ostream& operator<<(std::ostream& os, const private_functor<T>& pf) 
    { 
     pf.write(os); 
     return os; 
    } 
    } 

    /// a public template function that is designed to allow an object to be emitted to a stream 
    /// returns a function object that calls T::write(std::ostream&) when placed into an 
    /// output stream 
    template<class T> 
    detail::private_functor emit(const T& t) { 
    return detail::private_functor<T>(t); 
    } 
} 

// can be used like this: 

int main() { 
    struct S { 
    void write(std::ostream& os) const { os << "{I am an S}"; } 
    }; 

    std::cout << cpputil::emit(S) << std::endl; 
    return 0; 
} 
Powiązane problemy