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

8
我正在阅读Accelerated 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

但在 median.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行,这样说是正确的吗?
3个回答

16

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时,你就在这样做。


嗨,UK,请问你能回答最后一个问题吗? - kmad

4
这意味着你可以在C++源代码中使用using ...。你也可以将它合理地放在一个私有头文件中,然后再包含它,但是没有外部用户会包含它。你只需要避免干扰客户的环境,将using放在他们必须包含的头文件中可能会导致这种情况发生。
在链接实现对象文件时,程序最终不会使用"using::"结构吗?using关键字只是对编译器的一种便利,而不会改变链接的内容。它只影响使用它的源代码。

2
"using"声明仅在编译时起作用,使您无需反复键入std::(或其他命名空间)。在自己的.cpp实现文件中,使用using声明是可以的,因为您对该文件具有控制权。如果将其包含在.h(头)文件中,则包括那些您无法控制甚至可能从未听说过的文件在内的每个包含该头文件的文件都将包含您的using声明。
经典示例是一个实现文件正在使用tr1::shared_ptr,而std::shared_ptr则是后来才出现的。如果您的头文件包含std::shared_ptr,则他们的代码将不再编译,并且很难知道原因。
顺便说一句,这也是为什么现在认为宏是邪恶的原因之一。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接