3

命名空间不像大多数其他事物那样被声明和定义,但命名空间等价于前向声明将是:

namespace X {}  // empty body

通常,您通过在其中放置其他声明来定义命名空间。但是这个“命名空间前向声明”是最简单的解决方案吗?空的命名空间有什么用?

4

2 回答 2

4

这是甚至出现在标准中的一个:声明一个使用指令来表示一个命名空间

namespace unique { }
using namespace unique;

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

于 2010-09-27T21:11:01.827 回答
2

我使用一个空的命名空间定义来简化递归函数的声明,其中一个“方面”是运算符重载。运算符被放置在自己的命名空间中,以允许根据需要在范围内选择性使用,而不是在标头包含在任何地方时强制使用(因此如果分辨率变得不明确则强制错误)。

示例

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 有一个类似的输出格式库,但我不知道他们是否使用相同的实现技术。

于 2010-10-01T21:47:41.737 回答