один и тот же идентификатор для типа и объекта в объявлении

Я наткнулся на реализацию функции, которая повторяет имя типа для параметра того же типа. Код компилируется и, кажется, делает именно то, что задумано. Вот минимизированная версия:

#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

1

Решение

Да, это действительно. Вы объявляете переменную (параметр) во внутренней области видимости, которая скрывает имя от внешней области видимости.

Конечно, не очень хорошая идея в этом случае.

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.

Но старайтесь избегать подобных вещей. Это быстро приводит к путанице и ошибкам.

2

Делая это, вы скрываете глобальное имя внутри функционального блока.

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

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

В словах Страуструпа:*

Объявление имени в блоке может скрыть объявление в
включающий блок или глобальное имя. То есть имя может быть переопределено как
ссылаются на другую сущность в блоке. После выхода из блока,
имя возобновляет свое прежнее значение.


* Страуструп: язык программирования C ++, 4-е издание; Раздел 6.3.4 Область применения; Страница 157

1
По вопросам рекламы [email protected]