C++,删除类头中的#include <vector>或#include <string>

bia*_*ias 4 c++ templates include

我想删除,如果可能的话,从我的类头文件中包含<vector>和<string>.string和vector都是头文件中声明的函数的返回类型.

我希望我可以这样做:

namespace std {
    template <class T>
    class vector;
}
Run Code Online (Sandbox Code Playgroud)

并且,在标头中声明向量并将其包含在源文件中.

是否有参考文献,包括您必须在标题中包含的情况,以及您可以将包含纳入源文件的情况?

Dav*_*eas 14

您无法安全地转发声明STL模板,至少如果您想要便携且安全地执行它.该标准清楚地表明了每个STL元素的最低要求,但为实现扩展留出了空间,可以添加额外的模板参数,只要它们具有默认值.也就是说:标准规定std :: vector是一个模板,它至少需要2个参数(类型和分配器),但在符合标准的实现中可以有任意数量的额外参数.

不包括字符串和向量标题有什么意义?当然,无论谁打算使用你的课程,都必须已经包含它,因为它在你的界面上.

当您询问有关何时包含以及何时转发声明的参考时,我的建议是:包括您界面中的所有内容,转发声明内部详细信息.

这里有更多的问题,简单的编译性能.如果您推送在标头之外的公共(或受保护)接口中的类型的包含,您将创建包含顺序的依赖项.用户必须知道在包含标题之前必须包含字符串,因此您需要给他们一个额外的担心.

实现文件中应包含哪些内容:实现细节,记录器,不影响接口的元素(数据库连接器,文件头),内部实现细节(即使用STL算法实现,不会影响您的界面,仿函数)为简单目的而创建的,实用程序...)


小智 11

除了极少数例外,您不能向std添加内容:命名空间.对于像vector和string这样的类,你没有选择,只能#include相关的标准头文件.

另外,请注意string不是类,而是typedef basic_string<char>.

  • 前向声明不会在std命名空间中添加任何内容,只会告诉编译器有关已存在的内容.此外,规则不是那么严格:只要符合标准,就可以在std命名空间内为特定类型添加模板特化."程序可能会将任何标准库模板的模板特化添加到命名空间std.这会导致未定义的行为,除非声明依赖于用户定义的外部链接名称,除非特化符合原始模板的要求" (6认同)

Fre*_*son 6

这对于向量或字符串没有帮助,但值得一提的是iostream有一个前向引用头,称为iosfwd.

  • iosfwd是前瞻性宣言实力的愉快示范. (2认同)

Jem*_*Jem 5

没有简单明显的方法可以做到这一点(正如其他人已经解释得很好)。

然而,这些标头应该被视为语言的一部分(真的!),因此您可以将它们放入您自己的标头中,没有任何问题,没有人会抱怨。

如果您关心的是编译速度,我鼓励您使用预编译头,并将这些 std 头放入其中(除其他外)。它将显着提高你的编译速度。

抱歉,“真正的胜利者是避免战斗的人”这种答案。