Идентификаторы (C++)
Идентификатор — это последовательность символов, используемая для обозначения одного из следующих элементов:
- Имени объекта или переменной
- Имени класса, структуры или объединения
- Имени перечисленного типа
- Члена класса, структуры, объединения или перечисления
- Функции или функции члена класса
- Имени определения типа (typedef)
- Label name
- Имени макроса
- Параметра макроса
Следующие символы можно использовать в качестве любого символа идентификатора:
_ a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
В идентификаторе также можно использовать определенные диапазоны универсальных имен символов. Универсальное имя в идентификаторе не может обозначать управляющий символ или символ в основной кодировке исходного кода. Дополнительные сведения см. в разделе Character Sets. Следующие диапазоны номеров кодовых точек Юникода можно использовать как универсальные имена символов для любого символа в идентификаторе.
- 00A8, 00AA, 00AD, 00AF, 00B2-00B5, 00B7-00BA, 00BC-00BE, 00C0-00D6, 00D8-00F6, 00F8-00FF, 0100-02FF, 0370-167F, 1681-180D, 180F-1DBF, 1E00-1FFF, 200B-200D, 202A-202E, 203F-2040, 2054, 2060-206F, 2070-20CF, 2100-218F, 2460-24FF, 2776-2793, 2C00-2DFF, 2E80-2FFF, 3004-3007, 3021-302F, 3031-303F, 3040-D7FF, F900-FD3D, FD40-FDCF, FDF0-FE1F, FE30-FE44, FE47-FFFD, 10000-1FFFD, 20000-2FFFD, 30000-3FFFD, 40000-4FFFD, 50000-5FFFD, 60000-6FFFD, 70000-7FFFD, 80000-8FFFD, 90000-9FFFD, A0000-AFFFD, B0000-BFFFD, C0000-CFFFD, D0000-DFFFD, E0000-EFFFD
Следующие символы могут быть любым символом в идентификаторе, кроме первого:
0 1 2 3 4 5 6 7 8 9
Следующие диапазоны номеров кодовых точек Юникода также можно использовать как универсальные имена символов для любого символа в идентификаторе, кроме первого:
- 0300-036F, 1DC0-1DFF, 20D0-20FF, FE20-FE2F
Блок, относящийся только к системам Майкрософт
Значимыми являются только первые 2048 символов идентификаторов Microsoft C++. Для имен пользовательских типов компилятор создает «внутренние» имена, чтобы сохранить информацию о типе. Длина такого имени, включая информацию о типе, не может превышать 2048 символов. (См. раздел Украшенные имена для получения дополнительных сведений .) Факторы, которые могут повлиять на длину декорированного идентификатора:
- Обозначает ли идентификатор объект пользовательского типа или типа, производного от пользовательского типа.
- Обозначает ли идентификатор функцию типа, производного от функции.
- Количество аргументов функции.
Знак доллара $ является допустимым символом идентификатора в компиляторе Microsoft C++ (MSVC). MSVC также позволяет использовать фактические символы, представленные допустимыми диапазонами универсальных имен символов в идентификаторах. Чтобы использовать эти символы, необходимо сохранить файл в той кодировке, которая включает эти символы. В этом примере показано, как можно взаимозаменяемо использовать в коде расширенные символы и универсальные имена символов.
// extended_identifier.cpp // In Visual Studio, use File, Advanced Save Options to set // the file encoding to Unicode codepage 1200 struct テスト // Japanese 'test' < void トスト() <>// Japanese 'toast' >; int main() < テスト \u30D1\u30F3; // Japanese パン 'bread' in UCN form パン.トスト(); // compiler recognizes UCN or literal form >
Диапазон разрешенных символов в идентификаторе шире, чем при компиляции кода C++/CLI. Идентификаторы в коде, скомпилированном с помощью /clr, должны соответствовать стандарту ECMA-335: Common Language Infrastructure (CLI).
Завершение блока, относящегося только к системам Майкрософт
Первый символ идентификатора должен быть алфавитным символом (в верхнем или нижнем регистре) или символом подчеркивания ( _ ). Поскольку в идентификаторах C++ учитывается регистр, идентификаторы fileName и FileName различаются.
Идентификаторы не могут иметь то же написание и регистр, что и ключевые слова. Идентификаторы, в которых содержатся ключевые слова, являются допустимыми. Например, идентификатор Pint будет допустимым даже несмотря на то, что в него входит ключевое слово int .
Использование двух последовательных символов подчеркивания (___) в идентификаторе или один начальный символ подчеркивания, за которым следует буква буквы, зарезервировано для реализаций C++ во всех область. В области видимости файла не следует использовать идентификаторы, начинающиеся с одного символа подчеркивания, за которым следует строчная буква. Это связано с возможными конфликтами с уже существующими или будущими зарезервированными идентификаторами.
Ошибка компилятора C2065
Компилятор не может найти объявление для идентификатора. Существует множество возможных причин этой ошибки. Наиболее распространенными причинами C2065 являются то, что идентификатор не был объявлен, идентификатор не указан, заголовок, в котором объявлен идентификатор не включен в файл, или идентификатор отсутствует область квалификатор, например cout std::cout вместо этого. Дополнительные сведения о объявлениях в C++см. в статьях «Объявления и определения» (C++).
Ниже приведены некоторые распространенные проблемы и решения более подробно.
Идентификатор не является необъявленным
Если идентификатор является переменной или именем функции, его необходимо объявить, прежде чем его можно будет использовать. Объявление функции должно также включать типы его параметров, прежде чем можно будет использовать функцию. Если переменная объявлена с помощью auto , компилятор должен иметь возможность выводить тип из инициализатора.
Если идентификатор является членом класса или структуры или объявлен в пространстве имен, он должен быть квалифицирован по имени класса или структуры или имени пространства имен при использовании вне структуры, класса или пространства имен область. Кроме того, пространство имен должно быть передано в область директивой, например using namespace std; , или имя члена должно быть передано в область using объявлением using , например using std::string; . В противном случае необъявленное имя считается необъявленным идентификатором в текущем область.
Если идентификатор является тегом для определяемого пользователем типа, например a class или struct , тип тега необходимо объявить, прежде чем его можно будет использовать. Например, объявление struct SomeStruct < /*. */ >; должно существовать, прежде чем можно объявить переменную SomeStruct myStruct; в коде.
Если идентификатор является псевдонимом типа, тип должен быть объявлен объявлением using или typedef перед его использованием. Например, необходимо объявить using my_flags = std::ios_base::fmtflags; , прежде чем использовать my_flags его в качестве псевдонима std::ios_base::fmtflags типа.
Пример: неправильный идентификатор
Эта ошибка обычно возникает, когда имя идентификатора заглавно или идентификатор использует неправильные буквы верхнего и нижнего регистра. Имя в объявлении должно точно соответствовать используемому имени.
// C2065_spell.cpp // compile with: cl /EHsc C2065_spell.cpp #include using namespace std; int main() < int someIdentifier = 42; coutПример. Использование идентификатора un область d
Эта ошибка может возникать, если идентификатор неправильно область. Если вы видите C2065 при использовании cout , область проблема является причиной. Если функции и операторы стандартной библиотеки C++ не являются полными по пространству имен или вы не довели std пространство имен в текущую using область с помощью директивы, компилятор не может найти их. Чтобы устранить эту проблему, необходимо полностью указать имена идентификаторов или указать пространство имен с помощью директивы using .
Этот пример не может компилироваться из-за того, что cout он endl определен в std пространстве имен:
// C2065_scope.cpp // compile with: cl /EHsc C2065_scope.cpp #include // using namespace std; // Uncomment this line to fix int main() < coutИдентификаторы, объявленные внутри , struct или enum class типы, также должны быть квалифицированы по имени их вложенных class область при их использовании за пределами этого область.
Пример: предварительно скомпилированные заголовки не первый
Эта ошибка может возникать, если вы помещаете какие-либо директивы препроцессора, например #include , #define или #pragma до #include предварительно скомпилированного файла заголовка. Если исходный файл использует предварительно скомпилированный файл заголовка (то есть, если он компилируется с помощью /Yu параметра компилятора), все директивы препроцессора перед предварительной компиляцией файла заголовка игнорируются.
Этот пример не может компилироваться из-за того, что он endl определен в заголовке, который игнорируется, так как cout он включен перед предварительно скомпилированным файлом заголовка. Чтобы создать этот пример, создайте все три файла, а затем скомпилируйте (некоторые версии Visual Studio), stdafx.cpp а затем скомпилируйте. pch.h C2065_pch.cpp
// pch.h (stdafx.h in Visual Studio 2017 and earlier) #includeИсходный pch.h файл: stdafx.h
// pch.cpp (stdafx.cpp in Visual Studio 2017 and earlier) // Compile by using: cl /EHsc /W4 /c /Ycstdafx.h stdafx.cpp #include "pch.h"Исходный файл C2065_pch.cpp :
// C2065_pch.cpp // compile with: cl /EHsc /W4 /Yustdafx.h C2065_pch.cpp #include #include "stdafx.h" using namespace std; int main() < coutЧтобы устранить эту проблему, добавьте #include в предварительно скомпилированный файл заголовка или переместите его после добавления предварительно скомпилированного файла заголовка в исходный файл.
Пример: отсутствующий файл заголовка
Ошибка может возникнуть, если вы не включили файл заголовка, объявляющий идентификатор. Убедитесь, что файл, содержащий объявление идентификатора, включается в каждый исходный файл, использующий его.
// C2065_header.cpp // compile with: cl /EHsc C2065_header.cpp //#include int main() < fpos_t file_position = 42; // C2065: 'fpos_t': undeclared identifier // To fix, uncomment the #include line // to include the header where fpos_t is defined >Еще одна возможная причина заключается в том, что вы используете список инициализаторов без включения заголовка .
// C2065_initializer.cpp // compile with: cl /EHsc C2065_initializer.cpp // #include int main() < for (auto strList : ) if (strList == "hello") // C2065: 'strList': undeclared identifier return 1; // To fix, uncomment the #include line >Эта ошибка может появить в исходных файлах классического приложения Windows, если вы определяете VC_EXTRALEAN или WIN32_LEAN_AND_MEAN WIN32_EXTRA_LEAN . Эти макросы препроцессора исключают некоторые файлы заголовков из windows.h и afxv_w32.h для ускорения компиляции. windows.h Найдите и afxv_w32.h найдите актуальное описание того, что было исключено.
Пример: отсутствие закрывающей кавычки
Эта ошибка может возникать, если после строковой константы отсутствует закрывающая кавычка. Это простой способ запутать компилятора. Отсутствующие закрывающие кавычки могут быть несколькими строками до сообщаемого расположения ошибки.
// C2065_quote.cpp // compile with: cl /EHsc C2065_quote.cpp #include int main() < // Fix this issue by adding the closing quote to "Aaaa" char * first = "Aaaa, * last = "Zeee"; std::coutПример. Использование итератора за пределами цикла область
Эта ошибка может возникать, если вы объявляете переменную итератора в for цикле, а затем пытаетесь использовать эту переменную итератора за пределами область for цикла. Компилятор включает /Zc:forScope параметр компилятора по умолчанию. Дополнительные сведения см. в разделе "Поддержка итератора отладки".
// C2065_iter.cpp // compile with: cl /EHsc C2065_iter.cpp #include #include int main() < // char last = '!'; std::string letters< "ABCDEFGHIJKLMNOPQRSTUVWXYZ" >; for (const char& c : letters) < if ('Q' == c) < std::cout // last = c; > std::coutПример: удалено объявление препроцессора
Эта ошибка может возникать, если вы ссылаетесь на функцию или переменную, которая находится в условно скомпилированном коде, который не компилируется для текущей конфигурации. Ошибка также может возникать, если вы вызываете функцию в файле заголовка, который в настоящее время не поддерживается в среде сборки. Если определенные переменные или функции доступны только при определении определенного макроса препроцессора, убедитесь, что код, вызывающий эти функции, можно скомпилировать только при определении того же макроса препроцессора. Эта проблема легко обнаружить в интегрированной среде разработки: объявление функции неактивно, если необходимые макросы препроцессора не определены для текущей конфигурации сборки.
Ниже приведен пример кода, который работает при сборке в отладке, но не в выпуске:
// C2065_defined.cpp // Compile with: cl /EHsc /W4 /MT C2065_defined.cpp #include #include #ifdef _DEBUG _CrtMemState oldstate; #endif int main() < _CrtMemDumpStatistics(&oldstate); std::coutПример: сбой вычета типов C++/CLI
Эта ошибка может возникать при вызове универсальной функции, если аргумент предполагаемого типа не может быть выведен из используемых параметров. Дополнительные сведения см. в разделе "Универсальные функции" (C++/CLI).
// C2065_b.cpp // compile with: cl /clr C2065_b.cpp generic void G(int i) <> int main() < // global generic function call G(10); // C2065 G(10); // OK - fix with a specific type argument >Пример: параметры атрибута C++/CLI
Эта ошибка также может быть создана в результате работы соответствия компилятора, которая была выполнена для Visual Studio 2005: параметр проверка атрибутов Visual C++.
// C2065_attributes.cpp // compile with: cl /c /clr C2065_attributes.cpp [module(DLL, name=MyLibrary)]; // C2065 // try the following line instead // [module(dll, name="MyLibrary")]; [export] struct MyStruct < int i; >;Ошибка - необъявленный идентификатор
Когда программирую на C++ в Visual Studio , появляется ошибка в операторах сout и cin . Компилятор пишет, что эти операторы не объявлены (undeclared identifier). Подскажите, пожалуйста, что делать? Добавлено. Все равно ничего не получается
#include #include "stdafx.h" #include using namespace std; int main()< //объявление переменной: double V,T,alpha; //грави постоянная: const double g=9.8; //Ввод параметров: cout>V;-и здесь cout>T; alpha = asin(g*T/2*V); cout
- c++
- visual-c++