使用指令与使用声明 [英] Using directive vs using declaration

查看:56
本文介绍了使用指令与使用声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您能解释一下为什么此代码有效并打印16吗?

Can you explain why this code works and prints 16;

#include <iostream>

namespace X {
int  p = 5;
}
namespace Y {
int  p = 16;

using namespace X;
}

int main()
{
std::cout << Y::p;
}

以及此代码为何引发多重声明错误

and why this code throws error of multiple declaration

#include <iostream>

namespace X {
int  p = 5;
}
namespace Y {
int  p = 16;

using X::p;
}

int main()
{
std::cout << Y::p;
}

我听说using指令不仅仅是使用任何名称的声明的过程,因为它的工作方式似乎有所不同

I have heard that using directive isn't simply the process of using declaration of any name, as it seems to work differently

但是我不明白为什么,你能给出一些详细的解释吗?

But I can't understand why, could you give some detailed explanation ??

类似地,这可以很好地打印16,如果我仅使用X :: p的声明替换指令,则会抛出相同的错误

similarly this one works fine printing 16, if I replace using the directive with just the declaration of X::p it will throw the same error

 #include <iostream>

namespace X {
    int  p = 5;
}

int  p = 16;

using namespace X;

int main()
{
    std::cout << ::p;
    std::cout << "\n";

    return 0;
}

推荐答案

关键区别在于using声明是一个声明.而using指令则不是.我知道这听起来很愚蠢,但这就是差异的本质.前者实际上是在声明性区域中添加声明,而后者仅使某些名称在声明性区域中可用.

The key difference is that a using declaration is, well, a declaration. While a using directive is not. Sounds stupid, I know, but that's the nature of the difference. The former actually adds declarations to a declarative region, while the latter only makes certain names usable in a declarative region.

使名称在声明的范围内可使用,而不是进行声明,这是一件很薄弱的事情.如果存在另一个具有相同名称的声明,例如

Making a name usable in a certain scope, as opposed to declaring it, is intended to be a much weaker thing. The former is not considered during qualified lookup, if there's another declaration with the same name, as [basic.scope.hiding]/4 says:

在查找由名称空间名称限定的名称时, 否则将由 using-directive 使声明可见的声明 可以被名称空间中具有相同名称的声明隐藏 包含 using-directive

During the lookup of a name qualified by a namespace name, declarations that would otherwise be made visible by a using-directive can be hidden by declarations with the same name in the namespace containing the using-directive

这几乎解释了您的第一个代码段.由于使用了声明,因此有了该名称的声明,因此不考虑使用指令中可见的名称.不管先到是谁,声明总是更强.

And that pretty much explains your first code snippet. There's a declaration for that name, on account of the using declaration, so the name made visible by the using directive isn't considered. Doesn't matter which comes first, a declaration is always stronger.

您的第二个代码段在Y中为p提供了两个声明.当涉及到这些时,通常适用于声明的规则.第二个必须声明相同的内容,否则程序格式错误.没什么,真的.

Your second code snippet has two declarations for p in Y. And when it comes to those, the usual rules for declarations apply. The second one must declare the same thing, or the program is ill-formed. Nothing more to it, really.

最后,在您的第三个代码段中,与第一个代码段中的内容更多相同. [basic.lookup.qual]/4 这样说:

Finally, in your third code snippet, it's more of the same as in your first code snippet. [basic.lookup.qual]/4 says this:

由一元作用域运算符::​([expr.prim])前缀的名称是 在使用它的翻译单位的全球范围内查找. 该名称应在全局名称空间范围内声明,或为 由于以下原因其声明在全局范围内可见的名称 using-directive ([namespace.qual]).使用​:: 即使其标识符已隐藏也要引用的名称.

A name prefixed by the unary scope operator ​::​ ([expr.prim]) is looked up in global scope, in the translation unit where it is used. The name shall be declared in global namespace scope or shall be a name whose declaration is visible in global scope because of a using-directive ([namespace.qual]). The use of ​::​ allows a global name to be referred to even if its identifier has been hidden.

因此,除了要查找的名称空间之外,其他所有内容都与您的第一个示例类似.你们都声明了它,并通过using指令使其可用.我引用的第一段决定了必须选择的段.

So other than the namespace being looked up, everything else is just like your first example. You both declare it, and make it available by the using directive. The first paragraph I quoted determines which one must be picked.

这篇关于使用指令与使用声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆