声明中类型和对象的相同标识符
same identifier for type and object in declaration
我偶然发现了一个函数实现,该函数实现回收了相同类型的参数的类型名称。代码编译并且似乎完全符合预期。这是一个最小化版本:
#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++11(mingw32-g++ 4.9.2,随 CodeBlocks 16.01 一起提供(
- C++(GCC 6.3(
- C++14 (GCC 6.3(
- C++ 4.3.2 (GCC 4.3.2(
- C++14 (叮当 4.0(
所有人都毫无怨言地接受它。
我不认为这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:%dn", X.v);
return 0;
}
演示:http://ideone.com/nheZTa
是的,它是有效的。您正在内部作用域中声明一个变量(参数(,该变量(参数(在外部作用域中隐藏了该名称。
在这种情况下,当然不是一个好主意。
它是有效的。它从外部作用域中隐藏变量。像这样隐藏通常称为阴影,您的编译器可能有一个警告,您可以启用警告以告诉您何时发生(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.
但尽量避免做上述事情。它很快导致混乱和错误。
通过这样做,您可以在功能块中隐藏全局名称。
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: The C++ Programming Language, 4th Edition;第 6.3.4 节 范围;157 页
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 如何在C++中为增加但记住删除先前对象的对象分配唯一标识符
- 声明中类型和对象的相同标识符
- 用户创建的类对象实例化的未申请标识符
- 为什么我的类对象会导致未申报的标识符错误
- 试图传递对象时未申报的标识符
- 指向对象的指针的未声明标识符向量
- 使用对象标识符作为变量名
- C++对象未声明的标识符
- C++ 无法创建具有标识符的对象
- ASN1 对象标识符名称
- 对象标识符、返回值或变量
- c++错误:对全局变量和对象数组使用未声明的标识符
- 比较对象标识符与字符串
- 未声明的标识符,对象向量
- 创建的对象总是未定义,并且在初始化构造函数时期望有标识符
- 哪些容器存储通过不同标识符访问的对象