1

我偶然发现了一个函数实现,它为相同类型的参数回收类型名称。代码编译并且似乎完全符合预期。这是一个最小化的版本:

#include <iostream>

using namespace std;

struct X {
    int v;
};

void print_X(const X& X)   // <--- here the identifier X has *two different meanings*
{
    cout << "X.v:" << X.v << endl;
}

该代码是针对 Borland C++ 5.6.4 开发的

我尝试了几种不同且更新的编译器:

大家无怨无悔地接受它。

我不认为它是好的 C++,但是......

它是有效的 C++ 吗?如果是的话,它在未来是否有效?

更新

多么可怕!直到现在我才看到,对于简单的变量声明也是如此:

X X;

演示:http: //ideone.com/a9GM49

更新#2

C++ 与 C 语言共享此功能:

#include <stdio.h>

typedef struct X {
    int v;
} X;

int main()
{
    X X;
    X.v = 7;
    printf("X.v:%d\n", X.v);
    return 0;
}

演示:http: //ideone.com/nheZTa

4

3 回答 3

2

是的,它是有效的。您正在内部范围中声明一个变量(参数),该范围内隐藏了外部范围的名称。

在这种情况下,当然不是一个好主意。

于 2017-08-04T09:38:22.450 回答
2

这是有效的。它从外部范围隐藏变量。像这样隐藏通常称为遮蔽,您的编译器可能有一个警告,您可以启用它来告诉您它何时发生(gcc 有-Wshadow)。

这是另一个例子:

int x; // global variable - always accessible as ::x
int main(int x, char** argv) { // this 'x' hides global 'x'
    // This is the only place you can get at the argument 'x'
    // before it is hidden by the line below.
    int x; // this subsequently hides the function argument 'x'
    {
        int x; // hides the 'x' at function scope
        for (int x = 0; x < 42; ++x) { // this 'hides 'x' in our nested scope
            // The for loop induction variable 'x' is what's in scope here
        }
        // Now 'x' is again the nested-scope 'x'
    }
    // Here 'x' again refers to the function scope 'x'
}
// At any point in time you can get access to the 'x' that is directly
// in scope *or* the global 'x' (as '::x')
// But you cannot access the other 'x's until you are back in
// their respective scopes.

但尽量避免做上述的事情。它很快就会导致混乱和错误。

于 2017-08-04T10:04:22.190 回答
1

通过这样做,您将全局名称隐藏在功能块内。

void print_X(const X& X, const X& Y)  //won't compile

void print_X(const X& X){
   X myX;    //again, won't compile
}

用 Stroustrup 的话来说:*

块中名称的声明可以隐藏封闭块中的声明或全局名称。也就是说,可以重新定义名称以引用块内的不同实体。退出区块后,名称恢复其先前的含义。


* Stroustrup:C++ 编程语言,第 4 版;第 6.3.4 节范围;第 157 页

于 2017-08-04T09:59:16.737 回答