如何确定函数来自哪个include头文件

How to determine which include header file a function comes from?

本文关键字:include 文件 何确定 函数      更新时间:2023-10-16

在学习新函数时,我喜欢在调用它们时包含全名(例如,std::cin而不是cin)。是否有类似的方法来包含函数来源的标头?例如,有没有一种方法可以指定排序函数来自<algorithm>标头,而不是<iomanip>标头,或者其他什么?

例如,如果我可以使用类似std::algorithm::sort而不是std::sort的东西来调用sort,那就太酷了。标准库中内置了太多的头,因此仅使用std::*实际上并没有那么多信息,而且告诉我*的具体来源。

显然,随着我对C++的理解越来越好,这可能没有必要,但我的目标是了解哪些函数与哪些标头配合使用,以便更好地了解标准库。

如果没有这样的方法来指定函数,是否有一个函数可以用来确定提供函数的标头?

最终,我认为列出与每个标头相关联的函数将是一种很好的编码实践:

#include <iostream>  //std::cout, std::cin

这样人们就可以弄清楚什么来自哪里!既然c++社区对名字的清晰性有着令人钦佩的痴迷,为什么不做更多的工作呢?

注意:这个问题之所以可能,是因为C++是一种非常非Python语言。毕竟,"显式比隐式好"。:)

例如,有没有一种方法可以指定排序函数来自<algorithm>标头,而不是<iomanip>标头,或者其他什么?

否。C++作为一种编译语言(故意忽略预处理器)不知道头的文件名,因此它们与头中定义的对象和类型的名称无关。

如果有帮助,<iomanip>中没有std::sort

这也是一件奇怪的事情。重载解析是通过匹配参数类型来执行的,这足以消除歧义。

例如,如果我可以使用类似std::algorithm::sort而不是std::sort的东西来调用sort,那将是很酷的。标准库中内置了太多的头,因此仅使用std::*实际上并没有那么多信息,而且告诉我*的具体来源。

没关系。你不需要知道它是从哪里来的。编译器不需要知道它来自哪里。这与实际使用std::sort完全无关。

确实,C++标准库没有将其内容组织到许多子名称空间中,而是在大多数情况下使用顶级::std。可以说,这使得使用标准库进行编码变得更加神秘,但事实并非如此:这只会使查找规则复杂化,并使您在处理运算符重载、模板实例化和friend时的生活更加困难。

最终,我认为列出与每个标头相关联的函数将是一种很好的编码实践:

#include <iostream>  //std::cout, std::cin

这样人们就可以弄清楚什么来自哪里!既然c++社区对名字的清晰性有着令人钦佩的痴迷,为什么不做更多的工作呢?

虽然我对一些POSIX/Linux套接字标头这样做,这样我就知道将来可能会删除哪些套接字标头,但我不会对标准标头这样做。C++社区知道std::cout是在哪里声明的,如果他们忘记了,那么他们可以简单地查找它。

我从未听说有人想要这样的东西。

你可以做的一件事(这很乏味,所以在我看来不值得)是为自己创建名称空间,并在该名称空间中为你想要的每个名称使用using declarations

#include <iostream>
namespace iostream {
using std::cout;
using std::endl;
}
int main() {
iostream::cout << 24 << iostream::endl;
return 0;
}

不过,我的建议是不要这么做。只要说出它们的名字就可以了,每次你不确定它们来自哪里时都要上网搜索。随着时间的推移,你会毫不费力地学会它们。

指定或确定函数来自哪个include头文件的方法?

您通常会在遇到问题时执行此操作,例如试图找出符号丢失的原因或标头冲突发生的位置。正如Lightness Races in Orbit和Bolov指出的那样,这不是你通常在运行时所做的事情。

但如果你想这样做,请执行以下操作:

gcc -E t.c

如果t.c是:

$ cat t.c
#include <stdio.h>
int main(int argc, char* argv[])
{
return 0;
}

输出将类似于:

$ gcc -E t.c
# 1 "t.c"
# 1 "<command-line>"
# 1 "t.c"
# 1 "/usr/include/stdio.h" 1 3 4
# 28 "/usr/include/stdio.h" 3 4
# 1 "/usr/include/features.h" 1 3 4
# 323 "/usr/include/features.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/predefs.h" 1 3 4
# 324 "/usr/include/features.h" 2 3 4
# 356 "/usr/include/features.h" 3 4
...
# 866 "/usr/include/stdio.h" 3 4
extern FILE *popen (__const char *__command, __const char *__modes) ;
extern int pclose (FILE *__stream);
extern char *ctermid (char *__s) __attribute__ ((__nothrow__));
# 906 "/usr/include/stdio.h" 3 4
extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__));
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__));
# 936 "/usr/include/stdio.h" 3 4
# 2 "t.c" 2
int main(int argc, char* argv[])
{
return 0;
}

然后,通过grep管道传输输出,以找到感兴趣的函数。