typedef int abc;
class Some{
public:
abc foo(){...}
typedef double abc;
};
В приведенном выше коде я получаю сообщение об ошибке:
error: changes meaning of 'abc' from 'typedef int abc'
потому что в книге учебник по С ++, пятое издание, это говорит:
Определения классов обрабатываются в два этапа:
1. Во-первых, член декларации составлены.
2. Тела функций составляются только после все класс был замечен.
Но в коде здесь:
typedef int abc;
class Some{
public:
int foo(abc){...}
typedef double abc;
};
Я поставил abc
в списке параметров.
Но я не получил такой ошибки, и компилятор работает отлично.
почему последний код не даст мне никакой ошибки, похожей на первую?
Я не думаю, что есть какая-то причина. Эта ошибка не требует диагностики (в соответствии со Стандартом C ++), поэтому ее поведение фактически не определено, если в вашем коде есть эта ошибка.
Ваш компилятор просто не проверил список параметров на наличие этой ошибки, но вполне мог это сделать.
Вы должны квалифицировать это, Some::abc
:
typedef int abc;
class Some{
public:
Some::abc foo(){...}
typedef double abc;
};
Причина, по которой первый пример выдает ошибку, заключается в том, что поиск имени не учитывает тип возвращаемого значения. Но когда фактическое тело функции генерируется в выражении, в котором оно вызывается, компилятор будет использовать Some::abc
и найти несоответствие.
typedef int abc;
class Some{
public:
abc foo() { return abc(); } // during lookup/resolution, "abc" is known to be int, return type is not considered
typedef double abc;
};
int main()
{
Some s;
int x = s.foo(); // kaboom, return type is double.
}
Во втором примере переопределение типа несущественно, потому что во время поиска имени abc
известно, что это int, потому что определение внутреннего typedef еще не было замечено. Нет никаких последствий во время создания функции на сайте вызова, потому что тип возвращаемого значения также int. Там просто нет несоответствия.
typedef int abc;
class Some{
public:
int foo(abc) { return int(); } // during lookup/resolution, "abc" is known to be int
typedef double abc; // this will not have been seen yet in the previous line
};
int main()
{
Some s;
int x = 0;
s.foo(x); // OK, x is of type int
}
В MinGW, если возвращаемый тип функции-члена отображается как тип псевдонима, определенный объявлением typedef. Не допускается изменение его значения.
Запрашиваемое вами правило поиска имен по-прежнему действует, как обычно, введенное в учебнике по языку C ++ Липпмана на стр. 447 — поиск имен для объявлений членов класса.