2014-09-30 6 views
9

В C++ анонимное пространство имен эквивалентно:Что делать, если мне нужно анонимное пространство имен в заголовке?

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

Где $$$$ является своего рода уникальным идентификатором. Анонимное пространство имен полезно для кода, который не следует видеть вне модуля компиляции.

До сих пор так хорошо, однако недавно я начал писать код с шаблонами, такой код должен быть в заголовках, поэтому использование анонимных пространств имен не имеет большого смысла, поскольку простое включение заголовка аннулирует эффект изоляции.

Тогда возникает вопрос, каков предложенный способ в этом случае? Я начал использовать именованное пространство имен Private. Это на самом деле не останавливает всех, кто хочет использовать идентификаторы внутри, но по крайней мере он уменьшает конфликты имен до id «Private».

Есть ли лучшие способы? Предложения?

+5

AFAIK, что все, что вы можете сделать, библиотеки шаблонов часто используют пространство имен, таких как 'detail' для этой цели. – user657267

+0

В идеале весь ваш код должен находиться в каком-то пространстве имен. Поместите свои шаблоны в какое-то пространство имен под названием Utility, или Alpha или MyWork или что-то в этом роде. И включите функции помощи. –

+0

Thanks user657267; это было подтверждение, которое я искал. Я боялся, что мне не хватает очевидного. –

ответ

3

Stick with Privatenamespace (или используйте более популярные detail). Помните, что основная идея механизмов доступа C++ затрудняет их неправильное использование, а не невозможно. Защитите себя от несчастных случаев, а не от вредоносных атак.

4

Если вы отчаянно нуждаетесь в этой изоляции, почему бы и нет старого старого файла - static? Он был undeprecated:

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

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

Затем снова, если вам нужно только foo в пределах одной единицы перевода, то вероятно, вы только включить его в заголовок в этой единице трансляции, а затем это не имеет значения вообще, будь то «в заголовке». Поэтому просто не включайте шаблоны в другие единицы перевода, и вы уже в значительной степени достигли своей цели изоляции.

Для действительно гарантии изоляции для всех возможных конкретизаций (т.е. в том числе тех, которые вы создали в этом TU), используйте static, как указаны выше, или просто документировать свое намерение с помощью detail пространства имен.

+0

+1: Шаблоны должны быть только в заголовке, если вы хотите использовать их в нескольких TU. –

0

Наиболее обычным способом скрыть реализацию кода шаблона в заголовке является внедрение реализации в пространство имен с именем detail.

Например:

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