Kompilatorfel C2065

"identifierare" : odeklarerad identifierare

Anmärkningar

Kompilatorn kan inte hitta deklarationen för en identifierare. Det finns många möjliga orsaker till det här felet. De vanligaste orsakerna till C2065 är att identifieraren inte har deklarerats, identifieraren är felstavad, rubriken där identifieraren deklareras inte ingår i filen eller att identifieraren saknar en omfångskvalificerare, cout till exempel i stället std::coutför . Mer information om deklarationer i C++finns i Deklarationer och definitioner (C++).

Här följer några vanliga problem och lösningar i detalj.

Identifieraren är odeklarerad

Om identifieraren är en variabel eller ett funktionsnamn måste du deklarera den innan den kan användas. En funktionsdeklaration måste också innehålla typerna av dess parametrar innan funktionen kan användas. Om variabeln deklareras med måste autokompilatorn kunna härleda typen från dess initialiserare.

Om identifieraren är medlem i en klass eller struct, eller deklareras i ett namnområde, måste den kvalificeras av klass- eller structnamnet, eller namnområdesnamnet, när det används utanför omfånget struct, klass eller namnområde. Alternativt måste namnområdet omfattas av ett using direktiv som using namespace std;, eller så måste medlemsnamnet omfattas av en using deklaration, till exempel using std::string;. Annars anses det okvalificerade namnet vara en odeklarerad identifierare i det aktuella omfånget.

Om identifieraren är taggen för en användardefinierad typ, till exempel en class eller struct, måste taggtypen deklareras innan den kan användas. Deklarationen struct SomeStruct { /*...*/ }; måste till exempel finnas innan du kan deklarera en variabel SomeStruct myStruct; i koden.

Om identifieraren är ett typalias måste typen deklareras av en using deklaration eller typedef innan den kan användas. Du måste till exempel deklarera using my_flags = std::ios_base::fmtflags; innan du kan använda my_flags som ett typalias för std::ios_base::fmtflags.

Exempel: felstavad identifierare

Det här felet uppstår ofta när identifierarnamnet är felstavat eller identifieraren använder fel versaler och gemener. Namnet i deklarationen måste exakt matcha det namn som du använder.

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

Exempel: Använd en identifierare som inte ärscoped

Det här felet kan inträffa om identifieraren inte är korrekt begränsad. Om du ser C2065 när du använder coutär ett omfångsproblem orsaken. När C++ StandardBiblioteksfunktioner och operatorer inte är fullständigt kvalificerade efter namnområde, eller om du inte har fört std in namnområdet i det aktuella omfånget med hjälp av ett using direktiv, kan kompilatorn inte hitta dem. För att åtgärda det här problemet måste du antingen fullständigt kvalificera identifierarnamnen eller ange namnområdet med using direktivet.

Det här exemplet kan inte kompileras eftersom cout och endl definieras i std namnområdet:

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

Identifierare som deklareras i class, structeller enum class typer måste också kvalificeras med namnet på deras omfång när du använder dem utanför det omfånget.

Exempel: Förkompilerad rubrik är inte först

Det här felet kan inträffa om du lägger till några förprocessordirektiv, till exempel #include, #defineeller #pragma, före #include en fördefinierad rubrikfil. Om källfilen använder en fördefinierad rubrikfil (dvs. om den kompileras med hjälp av kompileringsalternativet /Yu ) ignoreras alla förprocessordirektiv innan den förkompilerade huvudfilen ignoreras.

Det här exemplet kan inte kompileras eftersom cout och endl definieras i <iostream> rubriken, som ignoreras eftersom det ingår före den förkompilerade huvudfilen. Skapa det här exemplet genom att skapa alla tre filerna och sedan kompilera pch.h (vissa versioner av Visual Studio använder stdafx.cpp) och kompilera C2065_pch.cppsedan .

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

Källfilen pch.h eller 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"

Källfil 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
}

Åtgärda problemet genom att lägga till #include i <iostream> den förkompilerade huvudfilen eller flytta den efter att den förkompilerade rubrikfilen har inkluderats i källfilen.

Exempel: rubrikfil saknas

Felet kan inträffa om du inte har inkluderat huvudfilen som deklarerar identifieraren. Kontrollera att filen som innehåller deklarationen för identifieraren ingår i varje källfil som använder den.

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

En annan möjlig orsak är om du använder en initieringslista utan att ta med <initializer_list-huvudet> .

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

Du kan se det här felet i Källfilerna för Windows Desktop-appen om du definierar VC_EXTRALEAN, WIN32_LEAN_AND_MEANeller WIN32_EXTRA_LEAN. Dessa makron före processorn exkluderar vissa huvudfiler från windows.h och afxv_w32.h för snabb kompilering. Titta i windows.h och afxv_w32.h efter en up-to-date-beskrivning av vad som utesluts.

Exempel: slutcitat saknas

Det här felet kan inträffa om du saknar ett avslutande citattecken efter en strängkonstant. Det är ett enkelt sätt att förvirra kompilatorn. Den saknade avslutande offerten kan vara flera rader före den rapporterade felplatsen.

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

Exempel: Använd iteratorn utanför för loopomfång

Det här felet kan inträffa om du deklarerar en iteratorvariabel i en for loop och sedan försöker använda den iteratorvariabeln utanför loopens for omfång. Kompilatorn aktiverar kompilatoralternativet /Zc:forScope som standard. Mer information finns i Felsökning av iteratorstöd.

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

Exempel: Deklarationen för förprocessorn har tagits bort

Det här felet kan inträffa om du refererar till en funktion eller variabel som finns i villkorligt kompilerad kod som inte kompileras för den aktuella konfigurationen. Felet kan också inträffa om du anropar en funktion i en rubrikfil som för närvarande inte stöds i din byggmiljö. Om vissa variabler eller funktioner endast är tillgängliga när ett visst makro för processor har definierats kontrollerar du att koden som anropar dessa funktioner bara kan kompileras när samma makro för processor har definierats. Det här problemet är enkelt att upptäcka i IDE: Deklarationen för funktionen är nedtonad om de nödvändiga förprocessormakronen inte har definierats för den aktuella byggkonfigurationen.

Här är ett exempel på kod som fungerar när du skapar i Felsökning, men inte Release:

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

Exempel: Fel vid C++/CLI-typavdrag

Det här felet kan inträffa när du anropar en allmän funktion, om det avsedda typargumentet inte kan härledas från de parametrar som används. Mer information finns i Generiska funktioner (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
}

Exempel: C++/CLI-attributparametrar

Det här felet kan också genereras som ett resultat av kompilatorns efterlevnadsarbete som utfördes för Visual Studio 2005: parameterkontroll för Visual C++-attribut.

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