Что если мне понадобится анонимное пространство имен в заголовке?

В C ++ анонимное пространство имен эквивалентно:

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

Где $$$$ — это какой-то уникальный идентификатор. В этом случае анонимное пространство имен полезно для кода, который не должен просматриваться вне модуля компиляции.

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

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

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

9

Решение

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

3

Другие решения

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

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

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

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

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

4

Самый обычный способ скрыть реализацию кода шаблона в заголовке — поместить реализацию в пространство имен 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;
}
0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector