"using" C++标头实现中的关键字

"using" keyword in header implementation in C++

本文关键字:关键字 实现 using C++      更新时间:2023-10-16

我正在阅读加速 c++ 第 4 章,其中他们教授如何将 c++ 程序划分为不同的文件。在这里,他们写道,我们不应该在头文件中使用"using _::"结构,因为包含标头的人可能希望使用不同的实现。但是在实现头文件中的方法时,使用"using"是可以的。你能澄清一下吗?在链接实现对象文件时,程序最终不会使用"using::"构造吗?这是代码:

//median.h file
#ifndef GUARD_median_h
#define GUARD_median_h
#include <algorithm>
#include <vector>
double median(std::vector<double>); // <<<<<<<< no "using std::vector"
#endif

但在中位数.cpp:

#include <vector>
#include <stdexcept>
using std::vector; // <<<<< "using" construct used
using std::domain_error; // <<<<< "using" construct used
double median(vector<double> vec){
    if(vec.size() == 0) throw domain_error("median for an empty vector not defined");
    //....... rest of the implementation
}

澄清一下:

这是我的客户调用上面的标头:

#include "median.h"
using my_vector_impl::vector;
//..some function...
    std::vector v1;
    double med = median(v1);

我说我们阻止在标头中使用"std::vector"以便我们可以在上面的代码中使用第 2 行是否正确?

using只是缩短名称的编译时快捷方式。它在运行时不起作用。此外,它只影响在其自身范围内或以下的源代码,因此如果您在实现文件中使用它,则其他文件看不到它,但是如果您在标头中使用它,则包含标头的所有文件都将包含using,并且它们的命名空间将被污染。

编辑:

为了回答您更新的问题,您的示例并不是您应该避免在标题中using的原因。这就是为什么:

// Header:
using std::vector;
// Client:
#include <Header>
class vector { ... };
void f() {
    vector v; // Ambiguous because of something out of my control
}

这是您要避免的情况。您不想告诉使用您的库的人他们可以使用哪些名称,当您执行using时,您正在这样做。

这只是意味着您可以将using …放入C++源中。您也可以合理地将其放在包含但外部用户不会包含的私有标头中。您只是不想弄乱客户的环境,并且using放入他们需要包含的标头中可以做到这一点。

在链接实现对象文件时,程序最终不会使用"using::"构造吗?using关键字只是对编译器的方便,而不是更改链接内容的东西。它只影响使用它的来源。

"using"声明只是一个编译时构造,使您不必一遍又一遍地键入 std::(或其他命名空间)。 在您自己的.cpp实现文件中,可以使用 using 声明,因为您可以控制该文件。 如果将其包含在 .h(标头)文件中,则包含该标头的每个文件也将包含您的 using 声明,包括您无法控制的声明,甚至可能从未听说过。

一个典型的例子是使用 tr1::shared_ptr 的实现文件,而 std::shared_ptr 后来才出现。 如果您的头文件包含 std::shared_ptr,那么他们的代码将不再编译,他们很难知道原因。

顺便说一下,这也是为什么宏现在被认为是邪恶的。