2013-03-20 3 views
2
typedef int abc; 

class Some{ 
    public: 
     abc foo(){...} 
     typedef double abc; 
}; 

В приведенном выше коде, я понимаю, что я получаю сообщение об ошибке:поиск имен в списке параметров функции члена

error: changes meaning of 'abc' from 'typedef int abc' 

, потому что в книге C++ праймер, пятый Edtion, он говорит :

Class definitions are processed in two phases:

1.First, the member declarations are compiled.

2.Function bodies are compiled only after the entire class has been seen.

Но в коде здесь:

typedef int abc; 

class Some{ 
    public: 
     int foo(abc){...} 
     typedef double abc; 
}; 

Я установил abc в списке параметров. Но я не получил такую ​​ошибку, и компилятор работает отлично. Почему последний код не получит мне никакой ошибки, аналогичной предыдущей?

+0

На ваш вопрос? – Oswald

+0

мой плохой. Я отредактировал его. – longtengaa

ответ

1

Я не думаю, что нет причин. Эта ошибка не требует диагностики (в соответствии со стандартом C++), поэтому поведение не определено при возникновении этой ошибки в коде.

Ваш компилятор просто не проверил список параметров этой ошибки, но вполне мог бы это сделать.

0

Вы должны квалифицировать его, Some::abc:

typedef int abc; 

class Some{ 
    public: 
     Some::abc foo(){...} 
     typedef double abc; 
}; 
+0

Да, я это знаю. Но то, что я прошу здесь, - это то, почему последний код не будет предлагать ошибку, как это делал первый. – longtengaa

+0

Если вы хотите знать, почему последний код не будет запрашивать ошибку, как это делал первый, вы должны сказать это в вопросе, а не в комментарии к ответу. – Oswald

+0

Извините, я просто просто забыл, что ..... – longtengaa

0

Причина, по которой первый пример дает ошибку в том, что поиск имен не учитывает тип возвращаемого значения. Но когда фактическое тело функции генерируется в выражении, где оно вызывается, компилятор будет использовать 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 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 
} 
+0

Но не должно ли тело функции быть скомпилировано после того, как весь класс был замечен? – longtengaa

0

В MinGW, если тип возврата функции-члена отображается как тип псевдонима, определенный объявлением typedef. Нельзя изменять его значение. Правило поиска имени, которое вы запрашиваете, по-прежнему действует как обычно, представленное в Липпманском C++ Primer на стр. 447 - поиск имен для объявлений членов класса.

  1. Рассмотрено заявление членов класса, которые появляются перед использованием имени.
  2. Если поиск на шаге 1 не увенчался успехом, будут рассмотрены объявления, которые отображаются в области, в которой определяется класс, и которые отображаются перед определением класса.