简体   繁体   English

在C ++中的头实现中使用“using”关键字

[英]“using” keyword in header implementation in C++

I was reading Accelerated c++ chapter 4 where they teach about dividing a c++ program in different files. 我正在阅读Accelerated c ++第4章,他们教授如何在不同的文件中划分c ++程序。 Here, they write that we should not use the "using _:: " construct in header files because whoever is including the header might want to use a different implementation. 在这里,他们写道我们不应该在头文件中使用“using _ :: ”构造,因为包含头部的人可能想要使用不同的实现。 But while implementing the methods in the header file, the use of "using" is fine. 但是在头文件中实现方法时,使用“使用”很好。 Can you please clarify this? 你能澄清一下吗? While linking the implementation object file, won't the program eventually use the "using::" construct? 在链接实现对象文件时,程序最终是否会使用“using ::”构造? Here is the code: 这是代码:

//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

But in median.cpp: 但是在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
}

To clarify a bit more: 澄清一点:

Here is my client calling the above header: 这是我的客户端调用上面的标题:

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

Am I right in saying that we prevent "using std::vector" in header so that we can use line 2 in above code? 我是否正确地说我们在标题中阻止“使用std :: vector”以便我们可以在上面的代码中使用第2行?

using is simply a compile-time shortcut to shorten names. using只是缩短名称的编译时快捷方式。 It has no effect at runtime. 它在运行时没有任何影响。 Also, it only affects the source code which is at or below its own scope, so if you use it in the implementation file, no other files can see it, but if you use it in the header, all the files that include the header will have the using in them and their namespace will be polluted. 此外,它只影响处于或低于其自身范围的源代码,因此如果您在实现文件中使用它,没有其他文件可以看到它,但如果您在标头中使用它,则包含标题的所有文件将在其中using它们的命名空间将被污染。

Edit: 编辑:

To answer your updated question, your example isn't quite why you should avoid using in headers. 要回答您更新的问题,您的示例并不是您应该避免在标题中using原因。 This is why: 这就是为什么:

// Header:

using std::vector;

// Client:

#include <Header>

class vector { ... };

void f() {
    vector v; // Ambiguous because of something out of my control
}

This is the situation you want to avoid. 这是您要避免的情况。 You don't want to tell the people who use your libraries what names they can use, which you are doing when you do using . 您不想告诉使用您库的人们可以使用哪些名称,这些名称在您using时正在执行。

This simply means you can put using … in your C++ source. 这只是意味着你可以在你的C ++源代码中using … You could also reasonably put it in a private header that you include but no external user would include. 您也可以合理地将它放在您包含的私有标头中,但不包括外部用户。 You just don't want to mess with your client's environment and putting using in a header that they are required to include could do that. 你只是不想惹你的客户的环境和投入using的,因为它们需要包括能做到这样的标题。

While linking the implementation object file, won't the program eventually use the "using::" construct? 在链接实现对象文件时,程序最终是否会使用“using ::”构造? The using keyword is just a convenience to the compiler, not something that changes what gets linked. using关键字只是编译器的一种便利,而不是改变链接的东西。 It only affects the sources that use it. 它只影响使用它的来源。

The "using" declaration is only a compile time construct, saving you from having to type std:: (or another namespace) over and over again. “using”声明只是一个编译时构造,使您不必反复键入std ::(或其他命名空间)。 In your own .cpp implementation file, it's fine to use a using declaration because you have control over that file. 在您自己的.cpp实现文件中,可以使用using声明,因为您可以控制该文件。 If you include it in a .h (header) file, every file that includes that header would also be including your using declaration, including the ones you don't have control over, and may never have even heard of. 如果将其包含在.h(标题)文件中,则包含该标题的每个文件也将包括您的使用声明,包括您无法控制的声明,甚至可能从未听说过。

A classic example would be an implementation file that's using tr1::shared_ptr, vs std::shared_ptr which only came along later. 一个典型的例子是使用tr1 :: shared_ptr和vsd :: shared_ptr的实现文件,后者只是稍后出现。 If your header file includes std::shared_ptr, then their code will no longer compile, and it's difficult for them to know why. 如果您的头文件包含std :: shared_ptr,那么他们的代码将不再编译,并且他们很难知道原因。

Incidentally, this is also why macros are now considered evil. 顺便说一句,这也是为什么宏现在被认为是邪恶的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM