提问人:user1245895 提问时间:3/3/2012 最后编辑:Rob Kennedyuser1245895 更新时间:8/23/2020 访问量:5530
为什么省略“#include < string>”有时只会导致编译失败?
Why does omission of "#include <string>" only sometimes cause compilation failures?
问:
我是 C++ 的初学者。当我写代码时,有时我写,代码工作,有时我不写,代码不工作。但有时它可以在没有.#include <string>
#include <string>
#include <string>
那么我必须编写代码才能正常工作吗?#include <string>
答:
如果使用在标准标头中声明的成员,则可以,必须直接或间接(通过其他标头)包含该标头。string
某些平台上的某些编译器可能会在每月的某个时间进行编译,即使您未能包含标头也是如此。这种行为是不幸的、不可靠的,并不意味着你不应该包含标题。
原因很简单,您已经包含了其他标准标头,这些标头也恰好包括 .但正如我所说,这通常不能被依赖,它也可能非常突然地改变(例如,当安装了新版本的编译器时)。string
始终包含所有必要的标头。不幸的是,似乎没有关于需要包含哪些标头的可靠在线文档。查阅书籍或官方 C++ 标准。
例如,以下代码使用我的编译器 ( 4.6) 进行编译:gcc
#include <iostream>
int main() {
std::string str;
}
但是,如果我删除第一行,即使标题实际上应该是不相关的,它也不会再编译。iostream
评论
<string>
std::pair
<utility>
<map>
std::pair
如果只是使用指向用户定义类型的指针/引用,则只需声明该类型:
class my_class;
void foo(const my_class& c);
但是,当您使用该值时,编译器需要知道大小以及类型的定义。
请记住,标准标头可能包含其他标头,这并不意味着所有实现都会自动执行此操作,因此您不能依赖它。
您包含的其他标头可能包含在其中。#include <string>
尽管如此,通常最好直接在代码中加入,即使对于成功构建不是绝对必要的,以防这些“其他”标头发生变化 - 例如,由于不同(或不同版本)的编译器/标准库实现、平台甚至只是构建配置。#include <string>
(当然,此讨论适用于任何标头,而不仅仅是<字符串>
。
虽然在特定的源文件中没有直接出现,但这并不意味着它没有被另一个头文件包含。考虑一下:#include <string>
文件:header.h
#if !defined(__HEADER_H__)
#define __HEADER_H__
// more here
#include <string>
// ...and here
#endif
文件:source1.cc
#include <string>
void foo()
{
// No error here.
string s = "Foo";
}
文件:source2.cc
#include <header.h>
void bar()
{
// Still no error, since there's a #include <string> in header.h
string s = "Bar";
}
文件:source3.cc
void zoid()
{
// Here's the error; no such thing as "string", since non of the
// previous headers had been included.
string s = "Zoid";
}
标头字符串不包含在其他标头中。标头字符串本身只有 includes。没有定义。因此,使用字符串所需的所有必要定义都在标头字符串包含的标头中。这些标头可能已被其他标头包含。然后一切正常。例如,标头 ios 包括 stringbuf,其中包括 ...
即使您没有显式包含字符串,它也已包含在内,因为您包含了另一个标准标头。例如,vector 可能包含字符串。当您包含 vector 时,vector 中的所有内容都将包含在您的文件中。
我认为 Cpp 的未来版本应该有一个 include_module 或 module 关键字;其中仅包含文件中的特定模块。因此,如果一个文件有 3 个类,我们只包含我们需要的类。
例如
-I “../mingw/lib/include”
module <string>
在目录中搜索定义字符串类的文件。编译速度会明显变慢。
正如布兰科所说:
您包含的其他标头中可能包含 #include。
让我们来看看包括:iostream
#include <bits/c++config.h>
#include <ostream>
#include <istream>
如果你检查你可以看到一些这样的,我们有:istream
include
iostream => istream => ios => iosfwd
在我们有字符串库!但这不是标准的,它是用于正向声明的。我们有:iosfwd
iosfwd
#include < bits/stringfwd.h> // 用于字符串转发声明。
和在:stringfwd.h
@file bits/stringfwd.h This is an internal header file, included by other library headers. Do not attempt to use it directly. @headername{string}
所以,你可以在没有.string
#include <string>
评论
these are not the droids you are looking for