如何转发在c ++中的命名空间下声明一个类,比如std :: string?

时间:2010-10-02 11:46:57

标签: c++

  

可能重复:
  C++, removing #include<vector> or #include<string> in class header
  Forward declare an STL container?

我想转发声明std :: string,顺便说一下,我可以转发声明一个结构吗?

3 个答案:

答案 0 :(得分:4)

std :: string是一个typedef,所以你不能只是转发声明它。您可以查找确切的声明,转发声明并自己定义typedef,但是您还必须转发声明char_traits和allocator。所以这个应该可能会起作用,虽然它不应该*:

namespace std
{
  template< class T, class Traits, class Allocator >
  class basic_string;

  template< class T >
  struct char_traits;

  template< class T >
  class allocator;

  typedef basic_string< char, char_traits< char >, allocator< char > > string;
}

但最终你可能会更好。我也不确定这些声明在所有平台上是否完全相同,更不用说如果字符串头中的声明发生变化,它会导致的问题。

*见下面的评论

答案 1 :(得分:2)

一般来说,为了转发声明命名空间的类,你这样做:

namespace MyOtherNamespace
{
    class MyForwardedClass;
}

namespace MyNamespace
{
    MyOtherNamespace::MyForwardedClass * pClass;
}

但我怀疑std::可能存在一些限制,但不确定,我会检查。因为我记得因typedef引起的一些碰撞......

答案 2 :(得分:1)

简单回答:不要这样做。永远不要尝试从标准库(或者来自boost或cgal等)“转发声明”元素......你将在脚下自己动手。上面的帖子已经说明,你需要转发声明完整的类型定义。这很容易导致其他平台上的冲突或标准库的不同实现。

这是c ++的传统问题。未反映的包括std或boost导致不可接受的编译时间,来自模板实例的错误的疯狂传播等等。我已经在我们的一个项目中看到了它,那里没有线索的人在工作。您有多种选择可以避免或隐藏依赖项:

  1. 不要在API中公开这些元素,使用(const)char *,例如......
  2. 编写通用代码,现在不需要运行时类型
  3. 编写封装这些元素功能的接口,并允许您将依赖项移动到源文件中。
  4. 最佳变体将使用这三者的组合。