也许这是一个非常愚蠢的问题,但我正在阅读的书中指示我编写一段代码,使用算法对向量中的元素进行加扰和排序。为此,本书告诉我使用主C ++库中的算法库。好吧,到目前为止,我理解它,但在编写代码后,我想看看如果我从代码的顶部删除这个库会破坏什么,并且让我感到惊讶的是,一切仍然有效。
这是我正在谈论的代码。当我从代码的顶部删除“#include算法”时,没有任何中断。怎么会这样?不使用这个库时,'random_shuffle'部分不应该被破坏吗?
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
#include <cstdlib>
using namespace std;
int main()
{
vector<int>::const_iterator iter;
cout << "Creating a list of scores.";
vector<int> scores;
scores.push_back(1500);
scores.push_back(3500);
scores.push_back(7500);
cout << "\nHigh Scores:\n";
for (iter = scores.begin(); iter != scores.end(); ++iter)
{
cout << *iter << endl;
}
cout << "\nFinding a score.";
int score;
cout << "\nEnter a score to find: ";
cin >> score;
iter = find(scores.begin(), scores.end(), score);
if (iter != scores.end())
{
cout << "Score found.\n";
}
else
{
cout << "Score not found.\n";
}
cout << "\nRandomizing scores.";
srand(static_cast<unsigned int>(time(0)));
random_shuffle(scores.begin(), scores.end());
cout << "\nHigh Scores:\n";
for (iter = scores.begin(); iter != scores.end(); ++iter)
{
cout << *iter << endl;
}
cout << "\nSorting scores.";
sort(scores.begin(), scores.end());
cout << "\nHigh Scores:\n";
for (iter = scores.begin(); iter != scores.end(); ++iter)
{
cout << *iter << endl;
}
system("pause");
return 0;
}
答案 0 :(得分:7)
它起作用的原因是因为你已经包含的标题包含了它。
例如,矢量可能在其源中包含算法。这很常见,因为它们通常只是标题。
也就是说,您不能依赖标准库的具体实现来在每个标头中包含相同的内容。 (例如,可能与MSVC一起工作,它可能会破坏gcc stdlibc +++)。
出于这个原因,我强烈建议包括你使用的内容,无论它在哪里编译都没有。 ---请注意,这与“您引用的内容”略有不同,因为标题中的点和引用的前向声明可以显着缩短构建时间。
答案 1 :(得分:3)
C ++标准没有规定每个标准头包含哪些头。这意味着,例如,<vector>
可能#include <algorithm>
用于库实现A,但不在库实现B中。这也可能在同一库的不同版本之间或在其不同端口之间发生变化。例如,glibc ++曾经清理过他们的包含层次结构。
这使我们C ++程序员感到有些不适,因为我们应该确保包含正确的程序员,即使某些标准头文件已经这样做了;如果我们懒惰,我们冒险在其他平台上进行编译,系统升级和降级。
经验法则:
根据标题的定义包含必要的内容。但不是更多。
“但不是更多”,因为编译时间可能变得非常缓慢。
答案 2 :(得分:1)
代码有效,因为vector包含内部算法。 要验证包含的内容和不包含的内容,可以通过将-E标志传递给编译器来生成预处理器输出。
编写一个示例文件:temp.C只有一行:
#include <vector>
现在,如果我们将文件编译为g++ -E temp.C
,您将能够在输出中看到包含的算法。
答案 3 :(得分:0)
在这里休息
janus@Zeus:~$ g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:27:52: error: no matching function for call to ‘find(std::vector<int>::iterator, std::vector<int>::iterator, int&)’
test.cpp:27:52: note: candidate is:
/usr/include/c++/4.6/bits/streambuf_iterator.h:359:5: note: template<class _CharT2> typename __gnu_cxx::__enable_if<std::__is_char<_CharT2>::__value, std::istreambuf_iterator<_CharT2, std::char_traits<_CharT> > >::__type std::find(std::istreambuf_iterator<_CharT2, std::char_traits<_CharT> >, std::istreambuf_iterator<_CharT2, std::char_traits<_CharT> >, const _CharT2&)
test.cpp:39:48: error: ‘random_shuffle’ was not declared in this scope
test.cpp:47:38: error: ‘sort’ was not declared in this scope
janus@Zeus:~$
gcc 4.6.1
答案 4 :(得分:0)
当我删除#include算法行时,代码不能为我编译。听起来非常光顾的风险你确定你已经重新编译了吗?
我的编译器输出:
a.cpp(28) : error C3861: 'find': identifier not found
a.cpp(40) : error C3861: 'random_shuffle': identifier not found
a.cpp(48) : error C3861: 'sort': identifier not found
答案 5 :(得分:0)
不幸的是,标准标题允许包含其他标准标题,因此如果您忘记了代码,则无法保证您的代码会中断。
答案 6 :(得分:0)
#include
预处理程序指令不会在链接过程中“包含”库,只是指示预编译器读取头文件并将其包含在作为单个单元编译的源文件中。
也就是说,algorithm
头文件可能包含在另一个包含文件中。
注意:可以在头文件中声明特定的函数或方法并定义,因此不需要链接。
编辑:
您的代码写得很好,应该按预期工作。我只建议您使用换行预定义字符endl
并将其包含在输出序列的末尾,而不是在下一个开头:
cout << "Creating a list of scores." << endl;
cout << "High Scores:" << endl;