Udostępnij za pośrednictwem


Błąd kompilatora C2065

"identifier" : nierejestrowany identyfikator

Kompilator nie może odnaleźć deklaracji dla identyfikatora. Istnieje wiele możliwych przyczyn tego błędu. Najczęstszymi przyczynami C2065 jest to, że identyfikator nie został zadeklarowany, identyfikator jest błędnie napisany, nagłówek, w którym identyfikator jest zadeklarowany, nie jest uwzględniony w pliku lub brakuje identyfikatora kwalifikatora zakresu, na przykład cout zamiast std::cout. Aby uzyskać więcej informacji na temat deklaracji w języku C++, zobacz Deklaracje i definicje (C++).

Poniżej przedstawiono niektóre typowe problemy i rozwiązania bardziej szczegółowo.

Identyfikator jest niezadeklarowany

Jeśli identyfikator jest zmienną lub nazwą funkcji, należy ją zadeklarować, zanim będzie można jej użyć. Deklaracja funkcji musi również zawierać typy jego parametrów, zanim będzie można użyć funkcji. Jeśli zmienna jest zadeklarowana przy użyciu autometody , kompilator musi mieć możliwość wywnioskowania typu z inicjatora.

Jeśli identyfikator jest członkiem klasy lub struktury lub zadeklarowany w przestrzeni nazw, musi być kwalifikowany przez nazwę klasy lub struktury albo nazwę przestrzeni nazw, jeśli jest używana poza strukturą, klasą lub zakresem przestrzeni nazw. Alternatywnie przestrzeń nazw musi zostać wprowadzona do zakresu przez dyrektywę using , taką jak using namespace std;, lub nazwa elementu członkowskiego musi zostać wprowadzona do zakresu przez deklarację using , taką jak using std::string;. W przeciwnym razie niekwalifikowana nazwa jest uważana za niezdecydowany identyfikator w bieżącym zakresie.

Jeśli identyfikator jest tagiem typu zdefiniowanego przez użytkownika, na przykład , class structtyp tagu musi zostać zadeklarowany, zanim będzie można go użyć. Na przykład deklaracja struct SomeStruct { /*...*/ }; musi istnieć, zanim będzie można zadeklarować zmienną SomeStruct myStruct; w kodzie.

Jeśli identyfikator jest aliasem typu, typ musi być zadeklarowany przez deklarację using lub typedef zanim będzie można go użyć. Na przykład przed użyciem my_flags aliasu typu dla elementu std::ios_base::fmtflagsnależy zadeklarować using my_flags = std::ios_base::fmtflags; wartość .

Przykład: błędnie napisany identyfikator

Ten błąd występuje często, gdy nazwa identyfikatora jest błędna lub identyfikator używa nieprawidłowych wielkich i małych liter. Nazwa w deklaracji musi dokładnie odpowiadać używanej nazwie.

// 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;
}

Przykład: użyj identyfikatora niezakresowego

Ten błąd może wystąpić, jeśli identyfikator nie jest poprawnie o określonym zakresie. Jeśli podczas korzystania z usługi coutzostanie wyświetlony komunikat C2065, przyczyną jest problem z zakresem. Jeśli funkcje i operatory biblioteki standardowej języka C++ nie są w pełni kwalifikowane przez przestrzeń nazw lub nie wprowadzono std przestrzeni nazw do bieżącego using zakresu przy użyciu dyrektywy, kompilator nie może ich znaleźć. Aby rozwiązać ten problem, należy w pełni zakwalifikować nazwy identyfikatorów lub określić przestrzeń nazw za pomocą using dyrektywy .

Nie można skompilować tego przykładustd, ponieważ cout element jest endl zdefiniowany w przestrzeni nazw:

// 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;
}

Identyfikatory zadeklarowane wewnątrz classtypu , structlub enum class muszą być również kwalifikowane przez nazwę otaczającego zakresu, gdy są używane poza tym zakresem.

Przykład: prekompilowany nagłówek nie jest pierwszy

Ten błąd może wystąpić, jeśli umieścisz jakiekolwiek dyrektywy preprocesora, takie jak #include, #definelub #pragma, przed #include prekompilowany plik nagłówka. Jeśli plik źródłowy używa wstępnie skompilowanego pliku nagłówka (czyli jeśli jest kompilowany przy użyciu /Yu opcji kompilatora), wszystkie dyrektywy preprocesora przed wstępnie skompilowanym plikiem nagłówka zostaną zignorowane.

Nie można skompilować tego przykładu, ponieważ cout element jest endl zdefiniowany w nagłówku <iostream> , który jest ignorowany, ponieważ jest dołączany przed wstępnie skompilowany plik nagłówka. Aby skompilować ten przykład, utwórz wszystkie trzy pliki, a następnie skompiluj pch.h (niektóre wersje programu Visual Studio używają stdafx.cpp), a następnie skompiluj polecenie C2065_pch.cpp.

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

Plik pch.h źródłowy lub 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"

Plik C2065_pch.cppźródłowy:

// 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
}

Aby rozwiązać ten problem, dodaj #include <iostream> do wstępnie skompilowanego pliku nagłówka lub przenieś go po dołączeniu wstępnie skompilowanego pliku nagłówka do pliku źródłowego.

Przykład: brak pliku nagłówka

Błąd może wystąpić, jeśli nie dołączono pliku nagłówka, który deklaruje identyfikator. Upewnij się, że plik zawierający deklarację identyfikatora znajduje się w każdym pliku źródłowym, który go używa.

// 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
}

Inną możliwą przyczyną jest użycie listy inicjatora bez dołączania nagłówka <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
}

Ten błąd może wystąpić w plikach źródłowych aplikacji klasycznych systemu Windows, jeśli zdefiniujesz VC_EXTRALEAN, WIN32_LEAN_AND_MEANlub WIN32_EXTRA_LEAN. Te makra preprocesora wykluczają niektóre pliki nagłówkowe z windows.h i afxv_w32.h w celu przyspieszenia kompilacji. windows.h afxv_w32.h Poszukaj aktualnego opisu wykluczonych elementów.

Przykład: brak cudzysłowu zamykającego

Ten błąd może wystąpić, jeśli brakuje cudzysłowu zamykającego po stałej ciągu. Jest to prosty sposób dezorientowania kompilatora. Brak cudzysłowu zamykającego może być kilka wierszy przed zgłoszoną lokalizacją błędu.

// 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
}

Przykład: użyj iteratora poza zakresem pętli

Ten błąd może wystąpić, jeśli zadeklarujesz zmienną iteratora w for pętli, a następnie spróbujesz użyć tej zmiennej iteratora poza zakresem for pętli. Kompilator domyślnie włącza opcję kompilatora /Zc:forScope . Aby uzyskać więcej informacji, zobacz Obsługa iteratora debugowania.

// 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
}

Przykład: deklaracja usunięcia preprocesora

Ten błąd może wystąpić, jeśli odwołujesz się do funkcji lub zmiennej, która jest w warunkowo skompilowanym kodzie, który nie jest kompilowany dla bieżącej konfiguracji. Błąd może również wystąpić, jeśli wywołasz funkcję w pliku nagłówkowym, który obecnie nie jest obsługiwany w środowisku kompilacji. Jeśli niektóre zmienne lub funkcje są dostępne tylko wtedy, gdy zdefiniowano określone makro preprocesora, upewnij się, że kod wywołujący te funkcje można skompilować tylko wtedy, gdy zdefiniowano to samo makro preprocesora. Ten problem jest łatwy do wykrycia w środowisku IDE: deklaracja funkcji jest wyszarzona, jeśli wymagane makra preprocesora nie są zdefiniowane dla bieżącej konfiguracji kompilacji.

Oto przykład kodu, który działa podczas kompilowania w debugowanie, ale nie wydania:

// 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
}

Przykład: błąd potrącenia typu C++/CLI

Ten błąd może wystąpić podczas wywoływania funkcji ogólnej, jeśli nie można wywołać zamierzonego argumentu typu z użytych parametrów. Aby uzyskać więcej informacji, zobacz Funkcje ogólne (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
}

Przykład: parametry atrybutu C++/CLI

Ten błąd można również wygenerować w wyniku pracy kompilatora, która została wykonana dla programu Visual Studio 2005: sprawdzanie parametrów dla atrybutów 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;
};