【问题标题】:Why is <algorithm> not needed for std::copy or std::swap?为什么 std::copy 或 std::swap 不需要 <algorithm>?
【发布时间】:2014-01-05 22:15:29
【问题描述】:

根据此cplusplus.com 页面,std::copy 位于 &lt;algorithm&gt; 标头中,std::swap 也是如此,但这是有效的:

#include <iostream>  // std::cout
#include <vector>  // std::vector
#include <iterator>  // std::ostream_iterator()
#include <cstdlib>  // rand(), srand()

// NOT including <algorithm>

int main()
{
  srand(time(NULL));

  const int SIZE = 10;
  std::vector<int> vec; 

  for(int i = 0; i < SIZE; ++i)
  {
     vec.push_back(rand() % 256);
  }

  copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, " "));
  std::cout << "\n";
}

我唯一能想到的是它们也是由&lt;vector&gt; 导出的...但是为什么我们需要&lt;algorithm&gt; 标头呢?

【问题讨论】:

  • &lt;algorithm&gt;(以及 C++11 中的 &lt;utility&gt;std::swap需要的。其他标题可能包含它们,但您不能依赖它。
  • 至少,你不应该依赖它。但是,是的,看看你的其他包括。他们正在拉入&lt;algorithm&gt;
  • 相关无意义的琐事:虽然 C++ 标准允许一个标准头包含另一个标准头,但 C 标准不允许这样做。
  • @MichaelBurr:这是否意味着如果标准头文件使用NULL,它必须定义它(在头文件中)而不是包含stddef.h/stdlib.h/etc?并且它必须从其他头文件中转发声明所需的函数而不是包含那些头文件?还是比这更严格?
  • @Cornstalks:在 C 中,标准标头通常不需要使用 NULL 的定义;有七个标题需要定义它。与函数的前向声明类似 - 标题中不需要这些(据我所知)。一些类型定义,如size_t,在多个头文件中声明;当用户包含多个标题时,实现通常会使用具有保留名称的宏来防止重新声明 typedef。

标签: c++ algorithm stl


【解决方案1】:

您在这里使用的&lt;vector&gt; 的特定实现可能包括copyswap 的定义(可能包括&lt;algorithm&gt;,或者可能包括其他一些包含它们的私有标头),但仅此而已只是一个实现细节,不能保证是可移植的。如果您要切换编译器,则完全有可能最终使用 C++ 标准库的实现,其中 copyswap 未由 &lt;vector&gt; 导入,在这种情况下,您的代码将不再编译.

换句话说,仅仅因为它恰好在您的编译器上工作并不意味着它是可移植的,因此为了最大程度的可移植性和正确性,无论如何您都应该包含&lt;algorithm&gt;

希望这会有所帮助!

【讨论】:

  • 不一定包括&lt;algorithm&gt;std::copy 可以在另一个文件中定义,该文件同时包含在 &lt;algorithm&gt;&lt;vector&gt; 中。
【解决方案2】:

“由&lt;vector&gt;导出”...

在 C++ 中,不会导出

但是,是的,&lt;vector&gt; 可以访问#include &lt;algorithm&gt;,这意味着当您使用&lt;vector&gt; 时,您可以访问所有&lt;algorithm&gt;。但为了安全起见,您仍然应该自己 #include &lt;algorithm&gt;,因为不同的实现(甚至不同的版本)可能不会这样做,如果您自己不包含它,它可能会破坏您的代码。

【讨论】:

  • 正确的措辞是什么?我猜导出更像是 Java 的东西?
  • @David:最好说“&lt;algorithm&gt; 可能包含在 &lt;vector&gt; 中”,但如果你在谈论函数 std::copystd::swap(而不是整个&lt;algorithm&gt; 标头),我可能会说“std::swapstd::copy 的声明可能(间接)包含在&lt;vector&gt; 中”。
【解决方案3】:

Clang 标准 C++ 库中&lt;vector&gt; 的实现包括&lt;algorithm&gt;。值得注意的是,std::vector&lt;T&gt; 有一个 swap() 方法,所以这可能是一个线索。

请记住,&lt;algorithm&gt; 中的算法在许多情况下都适用于迭代器,并且指针通常是可互换的。在不是 STL 容器的数据结构上使用包含在其中的算法是完全可行的。

【讨论】:

    猜你喜欢
    • 2021-10-01
    • 2016-09-07
    • 2011-08-30
    • 2012-07-28
    • 1970-01-01
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多