何时需要空名称空间定义?

时间:2010-09-27 21:01:24

标签: c++ namespaces forward-declaration

命名空间不像大多数其他东西那样被声明和定义,但是前向声明的命名空间将是:

namespace X {}  // empty body

通常,您可以通过在其中放置其他声明来定义命名空间。但这个“命名空间转发声明”是最容易解决的问题吗?什么用途是空名称空间?

2 个答案:

答案 0 :(得分:4)

这里甚至出现在标准中:声明一个using指令来表示命名空间

namespace unique { }
using namespace unique;

之后,您可以在其他时间打开命名空间并添加到其中,using指令使外部命名空间可以看到这些内容。

答案 1 :(得分:2)

我使用空命名空间定义来简化递归函数的声明,其中一个“side”是运算符重载。运算符放在它们自己的命名空间中,以允许根据需要选择性地使用作用域,而不是强制使用,如果标题包含在任何地方(如果分辨率变得模糊,则强制错误)。

Example

namespace container_inserters {}

template<class Stream, class Iter, class Ch>
void write_sequence(Stream& s, Iter begin, Iter end,
                    Ch const *initial, Ch const *sep, Ch const *final)
{
  using namespace container_inserters;
  if (initial) s << initial;
  if (begin != end) {
    s << *begin;
    ++begin;
    for (; begin != end; ++begin) {
      if (sep) s << sep;
      s << *begin;
    }
  }
  if (final) s << final;
}

namespace container_inserters {
#define G(N) \
template<class Ch, class Tr, class T, class A> \
std::basic_ostream<Ch,Tr>& operator<<(std::basic_ostream<Ch,Tr> &s, \
                                      N<T,A> const &value) \
{ \
  write_sequence(s, value.begin(), value.end(), "[", ", ", "]"); \
  return s; \
}
G(std::deque)
G(std::list)
G(std::vector)
#undef G
}  // container_inserters::

s << *begin的分辨率被延迟,直到write_sequence被实例化(因为它涉及模板参数),此时运算符已被声明并且可以通过using指令找到。对于嵌套容器,调用变为递归:

int main() {
  using namespace std;
  vector<deque<list<int> > > v (3, deque<list<int> >(2, list<int>(1, 42)));

  using namespace container_inserters;
  cout << v << '\n';

  return 0;
}
// output:
//  [[[42], [42]], [[42], [42]], [[42], [42]]]

Boost有一个类似的输出格式库,但我不知道它们是否使用相同的实现技术。