C++ コンパイラエラー C2793 の原因と解決策について解説
この解説では、Microsoft Visual Studio環境で発生するコンパイラ エラー C2793について説明します。
主にC++で見られるエラーですが、C言語と混同されることもあります。
例えば、__super::
の後に識別子やoperator
が指定されない場合に発生するエラーであり、その原因と修正方法について簡潔に解説します。
エラー概要
C2793エラーとは
C2793エラーは、C++で継承を用いる際に発生するコンパイルエラーです。
このエラーは、__super::
に続くトークンが不正な場合に表示され、正しい構文としては識別子またはキーワードoperator
を記述する必要があることを示しています。
たとえば、派生クラス内から基底クラスのメンバー関数を呼び出す際、関数名を省略して__super::()
と記述するとこのエラーが発生します。
エラーメッセージの構造と内容
エラーメッセージは以下のような形になっています。
・「’token’: 予期しないトークンが ‘::’ の後ろにあります。」
・「__super:: に続くことができる唯一のトークンは、識別子またはキーワード operator です。」
このメッセージは、__super::
に続けるべき正しいトークンが入力されなかった場合に表示されます。
具体的には、基底クラスの関数を呼び出す際に、呼び出す関数名や必要なキーワードが欠落している可能性を示しています。
発生原因の分析
__super::の使用に関する誤用
__super::
は、Microsoft拡張として用いられる継承クラスの基底クラスにアクセスするための記法ですが、誤った使い方が原因でエラーが発生します。
基底クラスのメンバー関数を呼び出す場合、正しい構文は__super::FunctionName()
のように、必ず基底クラスの関数名を明示する必要があります。
operatorキーワードの欠落パターン
特定の状況では、演算子のオーバーロードのためにoperator
キーワードを記述する必要があります。
たとえば、演算子関数を呼び出す場合は、__super::operator+()
のように記述します。
関数名やキーワードが欠落している場合、C2793エラーが発生し、コンパイラは不適切なトークンと判断します。
コンパイラの構文解析の動作
コンパイラは、__super::
の後に必ず識別子またはキーワードoperator
が続くことを期待しています。
トークンが不明確な場合、構文解析の段階で予期しないトークンエラーが発生します。
これは、コンパイラが継承関係における呼び出し対象を明確に決定するために必要な情報を求めているためです。
具体的には、関数名やオペレーター関数が正しく記述されていないと、コンパイラは適切な呼び出し先を特定できず、エラーと判断します。
解決策と対処法
正しい構文の記述方法
C2793エラーを回避するためには、__super::
の後に必ず呼び出す関数名またはキーワードoperator
を記述する必要があります。
例えば、基底クラスのメンバー関数を呼び出す場合は、関数名を明示することが求められます。
また、演算子をオーバーロードする場合は、operator
キーワードの指定が必須となります。
__super::の正しい使い方
基底クラスの関数を呼び出す場合、__super::
の後に正確な関数名を記述します。
たとえば、基底クラスにmf()
という関数がある場合、呼び出しは__super::mf();
と記述します。
この記述により、コンパイラは基底クラスのmf()
を正しく特定することができます。
operatorキーワードの配置方法
演算子のオーバーロードを行う場合は、__super::operator
に続きオーバーロードした演算子を記述します。
たとえば、加算演算子を呼び出す場合は__super::operator+()
というように記述します。
この構文により、演算子オーバーロードの意図が明確になり、エラーを回避できます。
誤り修正の手順
エラーが発生した場合、まずは該当行の__super::
の後に記述されているトークンを確認します。
以下のポイントに沿って修正を行います。
・基底クラスに実際に存在する関数名を確認する
・関数呼び出しの場合は、関数名を記述する
・演算子オーバーロードの場合は、operator
キーワードと共に適切な演算子記号を記述する
これらの手順に従うことで、エラー内容を解消し、正しい呼び出し構文に修正することができます。
コード例の比較
エラー発生例
修正前のコード例
以下のコードは、__super::
に関数名が記述されていないため、C2793エラーが発生する例です。
#include <iostream>
struct Base {
void mf() {
std::cout << "Base::mf が呼ばれました" << std::endl;
}
};
struct Derived : Base {
void mf() {
__super::(); // エラー C2793: 基底クラスの関数名が省略されている
}
};
int main() {
Derived d;
d.mf();
return 0;
}
// コンパイル時にエラーが発生します。
// エラーメッセージ例:
// 'token': 予期しないトークンが '::' の後ろにあります。
// __super:: に続くことができる唯一のトークンは、識別子またはキーワード operator です。
修正後の正しいコード例
以下のコードは、__super::mf()
と正しく記述することでC2793エラーが解消された例です。
#include <iostream>
struct Base {
void mf() {
std::cout << "Base::mf が呼ばれました" << std::endl;
}
};
struct Derived : Base {
void mf() {
// 基底クラスのmf()を正しく呼び出す
__super::mf();
}
};
int main() {
Derived d;
d.mf();
return 0;
}
Base::mf が呼ばれました
まとめ
本記事では、C++におけるC2793エラーの原因と解決策について解説しました。
エラーメッセージの内容、__super::の誤った記述方法、operatorキーワードの欠落による問題点などが詳しく説明されています。
また、正しい構文の記述方法や具体的な修正手順、サンプルコードを通じて修正前後の違いを確認できる内容となっています。