次の方法で共有


コンパイラ エラー C2065

'identifier' : 定義されていない識別子です

コンパイラでは、識別子の宣言を見つけることができません。 このエラーには多くの原因が考えられます。 C2065 の最も一般的な原因は、識別子が宣言されていない、識別子のスペルが間違っている、識別子が宣言されているヘッダーがファイルに含まれていない、識別子にstd::coutの代わりにスコープ修飾子がcoutされていないことです。 C++ での宣言の詳細については、「宣言と定義 (C++)」を参照してください。

ここでは、一般的な問題と解決方法について詳しく説明します。

識別子が宣言されていない

識別子が変数または関数名の場合は、それを使用する前に宣言する必要があります。 関数宣言には、関数を使用する前に、そのパラメーターの型も含める必要があります。 変数が auto を使用して宣言されている場合、コンパイラで初期化子から型を推論できる必要があります。

識別子がクラスまたは構造体のメンバーである場合、または名前空間で宣言されている場合は、クラスまたは構造体の名前、または名前空間のスコープ外で使用される場合は名前空間の名前で修飾する必要があります。 または、using namespace std; などの using ディレクティブによって名前空間をスコープ内に配置するか、メンバー名を using std::string; のような using 宣言によってスコープ内に配置する必要があります。 それ以外の場合、非修飾名は現在のスコープ内で宣言されていない識別子と見なされます。

識別子がユーザー定義型 (classstruct など) のタグである場合、タグの型は、使用する前に宣言する必要があります。 たとえば、コード内で変数 SomeStruct myStruct; を宣言する前に、宣言 struct SomeStruct { /*...*/ }; が存在している必要があります。

識別子が型エイリアスの場合は、使用する前に、 using 宣言または typedef で型を宣言する必要があります。 たとえば、my_flagsstd::ios_base::fmtflags の型の別名として使用するには、事前に using 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;
}

例: スコープを持たない識別子を使用する

このエラーは、識別子のスコープが正しくない場合に発生する可能性があります。 coutを使用するときに C2065 が表示される場合は、スコープの問題が原因です。 C++ 標準ライブラリの関数と演算子が名前空間によって完全修飾されていない場合、または using ディレクティブを使用して std 名前空間を現在のスコープに取り込んでいない場合、コンパイラはそれらを見つけることができません。 この問題を解決するには、識別子名を完全修飾するか、using ディレクティブを使用して名前空間を指定する必要があります。

この例では、coutendlstd 名前空間で定義されているため、コンパイルが失敗します。

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

classstructenum class 型の内部で宣言された識別子は、そのスコープの外部で使用する場合、外側のスコープの名前で修飾する必要があります。

例: プリコンパイル済みヘッダーが最初ではない

このエラーは、プリコンパイル済みヘッダー ファイルの#includeの前に、#include#define#pragmaなどのプリプロセッサ ディレクティブを配置した場合に発生する可能性があります。 ソース ファイルでプリコンパイル済みヘッダー ファイルが使用されている場合 (つまり、 /Yu コンパイラ オプションを使用してコンパイルされる場合)、プリコンパイル済みヘッダー ファイルの前にあるすべてのプリプロセッサ ディレクティブは無視されます。

この例では、 coutendl<iostream> ヘッダーで定義されているためコンパイルに失敗します。これは、プリコンパイル済みヘッダー ファイルの前に含まれているため無視されます。 この例をビルドするには、3 つのファイルをすべて作成し、 pch.h をコンパイルしてから (Visual Studio の一部のバージョンでは stdafx.cpp使用)、 C2065_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
}

この問題を解決するには、プリコンパイル済みヘッダー ファイルに <iostream> の #include を追加するか、プリコンパイル済みヘッダー ファイルをソース ファイルに含めた後に移動します。

例: ヘッダー ファイルがない

このエラーは、識別子を宣言するヘッダー ファイルを含めていない場合に発生する可能性があります。 識別子の宣言が含まれているファイルが、それを使用するすべてのソース ファイルに含まれていることを確認します。

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

VC_EXTRALEANWIN32_LEAN_AND_MEAN、または WIN32_EXTRA_LEAN を定義した場合、Windows のデスクトップ アプリのソース ファイルにこのエラーが表示されることがあります。 これらのプリプロセッサ マクロは、コンパイルを高速化するために windows.h および afxv_w32.h からいくつかのヘッダー ファイルを除外します。 除外対象の最新の説明については、 windows.hafxv_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 ループで反復子変数を宣言した後、for ループのスコープ外でその反復子変数を使用しようとした場合に発生する可能性があります。 コンパイラは、既定で /Zc:forScope コンパイラ オプションを有効にします。 詳細については、 Debug 反復子のサポートを参照してください。

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

例: プリプロセッサが削除された宣言

このエラーは、現在の構成用にコンパイルされていない条件付きでコンパイルされたコード内にある関数または変数を参照している場合に発生する可能性があります。 このエラーは、ビルド環境で現在サポートされていないヘッダー ファイルで関数を呼び出した場合にも発生する可能性があります。 特定のプリプロセッサ マクロが定義されている場合にのみ、特定の変数または関数を使用できる場合、同じプリプロセッサ マクロが定義されている場合にのみ、これらの関数を呼び出すコードをコンパイルできるようにします。 この問題は IDE で簡単に見つけることができます。現在のビルド構成に必要なプリプロセッサ マクロが定義されていない場合、関数の宣言はグレー表示されます。

デバッグでビルドするときに動作し、リリースでは動作しないコードの例を次に示します。

// 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 C++ 属性のパラメーター チェックを行う Visual Studio 2005 で行ったコンパイラ準拠作業の結果として生成されることもあります。

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