コンパイラ エラー C2065
'identifier' : 定義されていない識別子です
コンパイラでは、識別子の宣言を見つけることができません。 このエラーには多くの原因が考えられます。 C2065 の最も一般的な原因は、識別子が宣言されていない、識別子のスペルが間違っている、識別子が宣言されているヘッダーがファイルに含まれていない、識別子にstd::cout
の代わりにスコープ修飾子がcout
されていないことです。 C++ での宣言の詳細については、「宣言と定義 (C++)」を参照してください。
ここでは、一般的な問題と解決方法について詳しく説明します。
識別子が宣言されていない
識別子が変数または関数名の場合は、それを使用する前に宣言する必要があります。 関数宣言には、関数を使用する前に、そのパラメーターの型も含める必要があります。 変数が auto
を使用して宣言されている場合、コンパイラで初期化子から型を推論できる必要があります。
識別子がクラスまたは構造体のメンバーである場合、または名前空間で宣言されている場合は、クラスまたは構造体の名前、または名前空間のスコープ外で使用される場合は名前空間の名前で修飾する必要があります。 または、using namespace std;
などの using
ディレクティブによって名前空間をスコープ内に配置するか、メンバー名を using std::string;
のような using
宣言によってスコープ内に配置する必要があります。 それ以外の場合、非修飾名は現在のスコープ内で宣言されていない識別子と見なされます。
識別子がユーザー定義型 (class
や struct
など) のタグである場合、タグの型は、使用する前に宣言する必要があります。 たとえば、コード内で変数 SomeStruct myStruct;
を宣言する前に、宣言 struct SomeStruct { /*...*/ };
が存在している必要があります。
識別子が型エイリアスの場合は、使用する前に、 using
宣言または typedef
で型を宣言する必要があります。 たとえば、my_flags
を std::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
ディレクティブを使用して名前空間を指定する必要があります。
この例では、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;
}
class
、struct
、enum class
型の内部で宣言された識別子は、そのスコープの外部で使用する場合、外側のスコープの名前で修飾する必要があります。
例: プリコンパイル済みヘッダーが最初ではない
このエラーは、プリコンパイル済みヘッダー ファイルの#include
の前に、#include
、#define
、#pragma
などのプリプロセッサ ディレクティブを配置した場合に発生する可能性があります。 ソース ファイルでプリコンパイル済みヘッダー ファイルが使用されている場合 (つまり、 /Yu
コンパイラ オプションを使用してコンパイルされる場合)、プリコンパイル済みヘッダー ファイルの前にあるすべてのプリプロセッサ ディレクティブは無視されます。
この例では、 cout
と endl
が <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_EXTRALEAN
、WIN32_LEAN_AND_MEAN
、または WIN32_EXTRA_LEAN
を定義した場合、Windows のデスクトップ アプリのソース ファイルにこのエラーが表示されることがあります。 これらのプリプロセッサ マクロは、コンパイルを高速化するために 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
ループで反復子変数を宣言した後、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;
};