Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>В виндовых SDK/WDK, включая последние десяточные, полно конструкций такого вида:
ЕМ>#ifdef __cplusplus ЕМ>typedef class Xxx Xxx; ЕМ>#else ЕМ>typedef struct Xxx Xxx; ЕМ>#endif /* __cplusplus */
ЕМ>В альтернативной части безусловно есть смысл, а в основной? В каких случаях имя класса в C++ может не являться именем типа?
Это скорее всего сделано для совместимости с Си.
Re: Смысл явного дублирования имени класса через typedef
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>В альтернативной части безусловно есть смысл, а в основной? В каких случаях имя класса в C++ может не являться именем типа?
Здравствуйте, Евгений Музыченко, Вы писали:
NB>>попробуй в примере убрать class и поймешь
ЕМ>А, вот Вы о чем... А чем это лучше обычной опережающей декларации имени класса?
да в общем то, ничем, наверное
а чем хуже?
Re[6]: Смысл явного дублирования имени класса через typedef
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>В виндовых SDK/WDK, включая последние десяточные, полно конструкций такого вида:
ЕМ>#ifdef __cplusplus ЕМ>typedef class Xxx Xxx; ЕМ>#else ЕМ>typedef struct Xxx Xxx; ЕМ>#endif /* __cplusplus */
ЕМ>В альтернативной части безусловно есть смысл, а в основной? В каких случаях имя класса в C++ может не являться именем типа?
Дело может быть в порядке, в котором компилятор будет перебирать разные вещи, увидев в коде ссылку на Xxx. Т.е. сначала попытается найти локальную переменную, потом глобальную, потом подтянет using, потом явные typedefs, потом классы и структуры. Если между двумя последними пунктами есть что-то еще, то явный typedef повысит приоритет Xxx относительно этого чего-то.
Но не стоит исключать вариант, что это просто необдуманная копипаста в процессе исправления срочного бага.
Re[2]: Смысл явного дублирования имени класса через typedef
Здравствуйте, Quebecois, Вы писали:
Q>Дело может быть в порядке, в котором компилятор будет перебирать разные вещи, увидев в коде ссылку на Xxx. Т.е. сначала попытается найти локальную переменную, потом глобальную
Зачем ему искать переменные, когда Xxx используется, как имя типа?
Q>потом подтянет using, потом явные typedefs, потом классы и структуры. Если между двумя последними пунктами есть что-то еще, то явный typedef повысит приоритет Xxx относительно этого чего-то.
Разве промышленные компиляторы занимаются прямым перебором? Они должны иметь индексы на каждую категорию языковых объектов.
Q>Но не стоит исключать вариант, что это просто необдуманная копипаста в процессе исправления срочного бага.
Там таких typedef'ов 100500.
Re[3]: Смысл явного дублирования имени класса через typedef
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Зачем ему искать переменные, когда Xxx используется, как имя типа?
Потому что какой-то другой кусок кода где-то объявит Xxx по-другому, и тогда приоритет станет важен.
ЕМ>Разве промышленные компиляторы занимаются прямым перебором? Они должны иметь индексы на каждую категорию языковых объектов.
Я не говорю о скорости перебора. Я имел в виду результат компиляции.
ЕМ>Там таких typedef'ов 100500.
Которые могут генерироваться одной внутренней программой. Или быть описанными в guidelines, куда были скопированы из кривого фикса.
Re: Смысл явного дублирования имени класса через typedef
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ> В каких случаях имя класса в C++ может не являться именем типа?
Разумеется в случае, когда это имя является именем чего-то другого. Например, именем функции:
#if 1
class foo;
#else
typedef class foo foo;
#endif
const char* foo() {
return"fn";
}
Демо: https://godbolt.org/z/c31vh54xv — если не использовать typedef, то программа компилируется, но её поведение кардинально меняется от наличия объявления функции (второй define примера). И такое объявление функции в реальности будет не лежать рядом с классом, а приедет через пять транзитивных #include из какой-то другой библиотеки.
А typedef позволяет получить ошибку компиляции вместо ошибки во время исполнения программы.
Спасибо, полезно.
Вроде бы class в параметре функции должен дать понять компилятору, что мы хотим экземпляр класса, а не функцию, почему это не работает?
const char* foo() {
return "fn";
}
class foo {
};
std::ostream& operator<<(std::ostream& os, const class foo&) {
os << "cl";
return os;
}
И если убрать class из параметра функции, то clang дает очень вменяемое сообщение об ошибке
<source>:21:50: error: must use 'class' tag to refer to type 'foo' in this scope
std::ostream& operator<<(std::ostream& os, const foo&) {
^
class
<source>:13:13: note: class 'foo' is hidden by a non-type declaration of 'foo' here
const char* foo() {
^
1 error generated.
Пока выглядит что проблема тут только при использовании class c параметром
Re[3]: Смысл явного дублирования имени класса через typedef
Здравствуйте, Skorodum, Вы писали:
S>Вроде бы class в параметре функции должен дать понять компилятору, что мы хотим экземпляр класса, а не функцию, почему это не работает?
В параметре функции std::ostream& operator<<? Там отлично работает.
Дело-то в том, что эта функция потом не вызывается.
S>И если убрать class из параметра функции, то clang дает очень вменяемое сообщение об ошибке S>Пока выглядит что проблема тут только при использовании class c параметром
Вообще, const class foo& — это артефакт примера из-за того, что я зачем-то всунул определение функции в середину исходника. Можно легко переписать без него просто поменяв строки местами и получить тот же эффект.