Поделиться через


Ошибка компилятора C2065

"identifier" : необъявленный идентификатор

Компилятор не может найти объявление для идентификатора. Существует множество возможных причин этой ошибки. Наиболее распространенными причинами C2065 являются то, что идентификатор не был объявлен, идентификатор не указан, заголовок, в котором объявлен идентификатор не включен в файл, или идентификатор отсутствует область квалификатор, например coutstd::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 <iostream>
using namespace std;
int main() {
    int someIdentifier = 42;
    cout << "Some Identifier: " << SomeIdentifier << endl;
    // C2065: 'SomeIdentifier': undeclared identifier
    // To fix, correct the spelling:
    // cout << "Some Identifier: " << someIdentifier << endl;
}

Пример. Использование идентификатора un область d

Эта ошибка может возникать, если идентификатор неправильно область. Если вы видите C2065 при использованииcout, область проблема является причиной. Если функции и операторы стандартной библиотеки C++ не являются полными по пространству имен или вы не довели std пространство имен в текущую using область с помощью директивы, компилятор не может найти их. Чтобы устранить эту проблему, необходимо полностью указать имена идентификаторов или указать пространство имен с помощью директивы using .

Этот пример не может компилироваться из-за того, что cout он endl определен в std пространстве имен:

// C2065_scope.cpp
// compile with: cl /EHsc C2065_scope.cpp
#include <iostream>
// using namespace std;   // Uncomment this line to fix

int main() {
    cout << "Hello" << endl;   // C2065 'cout': undeclared identifier
                               // C2065 'endl': undeclared identifier
    // Or try the following line instead
    std::cout << "Hello" << std::endl;
}

Идентификаторы, объявленные внутри , structили enum class типы, также должны быть квалифицированы по имени их вложенных classобласть при их использовании за пределами этого область.

Пример: предварительно скомпилированные заголовки не первый

Эта ошибка может возникать, если вы помещаете какие-либо директивы препроцессора, например #include, #defineили #pragmaдо #include предварительно скомпилированного файла заголовка. Если исходный файл использует предварительно скомпилированный файл заголовка (то есть, если он компилируется с помощью /Yu параметра компилятора), все директивы препроцессора перед предварительной компиляцией файла заголовка игнорируются.

Этот пример не может компилироваться из-за того, что он endl определен в <iostream> заголовке, который игнорируется, так как cout он включен перед предварительно скомпилированным файлом заголовка. Чтобы создать этот пример, создайте все три файла, а затем скомпилируйте (некоторые версии Visual Studio), stdafx.cppа затем скомпилируйте.pch.hC2065_pch.cpp

// pch.h (stdafx.h in Visual Studio 2017 and earlier)
#include <stdio.h>

Исходный 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 <iostream>
#include "stdafx.h"
using namespace std;

int main() {
    cout << "Hello" << endl;   // C2065 'cout': undeclared identifier
                               // C2065 'endl': undeclared identifier
}

Чтобы устранить эту проблему, добавьте #include <iostream> в предварительно скомпилированный файл заголовка или переместите его после добавления предварительно скомпилированного файла заголовка в исходный файл.

Пример: отсутствующий файл заголовка

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

// C2065_header.cpp
// compile with: cl /EHsc C2065_header.cpp

//#include <stdio.h>
int main() {
    fpos_t file_position = 42; // C2065: 'fpos_t': undeclared identifier
    // To fix, uncomment the #include <stdio.h> line
    // to include the header where fpos_t is defined
}

Еще одна возможная причина заключается в том, что вы используете список инициализаторов без включения заголовка <initializer_list> .

// C2065_initializer.cpp
// compile with: cl /EHsc C2065_initializer.cpp

// #include <initializer_list>
int main() {
    for (auto strList : {"hello", "world"})
        if (strList == "hello") // C2065: 'strList': undeclared identifier
            return 1;
    // To fix, uncomment the #include <initializer_list> line
}

Эта ошибка может появить в исходных файлах классического приложения Windows, если вы определяете VC_EXTRALEANили WIN32_LEAN_AND_MEANWIN32_EXTRA_LEAN. Эти макросы препроцессора исключают некоторые файлы заголовков из windows.h и afxv_w32.h для ускорения компиляции. windows.h Найдите и afxv_w32.h найдите актуальное описание того, что было исключено.

Пример: отсутствие закрывающей кавычки

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

// C2065_quote.cpp
// compile with: cl /EHsc C2065_quote.cpp
#include <iostream>

int main() {
    // Fix this issue by adding the closing quote to "Aaaa"
    char * first = "Aaaa, * last = "Zeee";
    std::cout << "Name: " << first
        << " " << last << std::endl; // C2065: 'last': undeclared identifier
}

Пример. Использование итератора за пределами цикла область

Эта ошибка может возникать, если вы объявляете переменную итератора в for цикле, а затем пытаетесь использовать эту переменную итератора за пределами область for цикла. Компилятор включает /Zc:forScope параметр компилятора по умолчанию. Дополнительные сведения см. в разделе "Поддержка итератора отладки".

// C2065_iter.cpp
// compile with: cl /EHsc C2065_iter.cpp
#include <iostream>
#include <string>

int main() {
    // char last = '!';
    std::string letters{ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" };
    for (const char& c : letters) {
        if ('Q' == c) {
            std::cout << "Found Q!" << std::endl;
        }
        // last = c;
    }
    std::cout << "Last letter was " << c << std::endl; // C2065
    // Fix by using a variable declared in an outer scope.
    // Uncomment the lines that declare and use 'last' for an example.
    // std::cout << "Last letter was " << last << std::endl; // C2065
}

Пример: удалено объявление препроцессора

Эта ошибка может возникать, если вы ссылаетесь на функцию или переменную, которая находится в условно скомпилированном коде, который не компилируется для текущей конфигурации. Ошибка также может возникать, если вы вызываете функцию в файле заголовка, который в настоящее время не поддерживается в среде сборки. Если определенные переменные или функции доступны только при определении определенного макроса препроцессора, убедитесь, что код, вызывающий эти функции, можно скомпилировать только при определении того же макроса препроцессора. Эта проблема легко обнаружить в интегрированной среде разработки: объявление функции неактивно, если необходимые макросы препроцессора не определены для текущей конфигурации сборки.

Ниже приведен пример кода, который работает при сборке в отладке, но не в выпуске:

// C2065_defined.cpp
// Compile with: cl /EHsc /W4 /MT C2065_defined.cpp
#include <iostream>
#include <crtdbg.h>
#ifdef _DEBUG
    _CrtMemState oldstate;
#endif
int main() {
    _CrtMemDumpStatistics(&oldstate);
    std::cout << "Total count " << oldstate.lTotalCount; // C2065
    // Fix by guarding references the same way as the declaration:
    // #ifdef _DEBUG
    //    std::cout << "Total count " << oldstate.lTotalCount;
    // #endif
}

Пример: сбой вычета типов C++/CLI

Эта ошибка может возникать при вызове универсальной функции, если аргумент предполагаемого типа не может быть выведен из используемых параметров. Дополнительные сведения см. в разделе "Универсальные функции" (C++/CLI).

// C2065_b.cpp
// compile with: cl /clr C2065_b.cpp
generic <typename ItemType>
void G(int i) {}

int main() {
   // global generic function call
   G<T>(10);     // C2065
   G<int>(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;
};