C言語/C++を用いてプログラミングしていると「引数1を”から”へ変換できません」といったコンパイルエラーが発生することがあります。
これは変数名を打ち間違えているわけではないのですが、なぜこのようなコンパイルエラーが発生してしまうのでしょうか。
このページではC2664「引数1を”から”へ変換できません」の原因と対処法を解説しています。
C2664「引数1を”から”へ変換できません」の原因と対処法
C2664エラーが発生するのは、引数として渡した変数の型と関数で定義されている仮引数の型が一致しないことで発生します。
struct Data1 {
int x;
int y;
};
struct Data2 {
int x;
int y;
};
int Sum(Data1 data) {
return data.x + data.y;
}
int main() {
Data2 data{1,2};
int result = Sum(data); //C2664
return 1;
}
上記コードはSum関数でData1構造体を仮引数として定義していますが、main関数で渡しているのはData2構造体です。
Data1構造体とData2構造体の中身はどちらも同じですが、C言語は全く別の構造体として扱うため、型変換ができずにC2664エラーが発生します。
このエラーを修正したい場合は、定義している仮引数の型を変更するか、関数呼び出し元で渡している変数の型を修正するようにしてください。
int型やfloat型ではC2664エラーが発生しないのはなぜ?
以下の関数があったとしましょう。
float Sum(float a, float b) {
return a + b;
}
こちらの関数はfloat型の変数を仮引数として定義していますが、実はint型やchar型などの他の方の値を受け取ることができます。もちろんコンパイルエラーは起きません。
int型・float型といったC言語に標準で実装されている数値型は暗黙的型変換がされるようになっており、関数に引数を渡すときに型が異なっていた場合、自動的に変換(キャスト)してくれるのです。
そのため、以下のコードはコンパイルエラーになりません。
float Sum(float a, float b) {
return a + b;
}
int main() {
int a = 1;
int b = 2;
float c = Sum(a, b); //エラーにならない
return 0;
}
数値の範囲や扱い(小数を含めるかどうか)が異なるので、その点は注意しましょう。例えばfloat型変数をint型変数を受け取る関数に渡した場合、小数点以下が切り捨てられます。
区別しやすい構造体・クラス名にするように
構造体・クラスの実装が全く同じだったとしても、構造体名・クラス名が異なれば全く別の型として扱われます。
ですので、構造体やクラスを定義するときはData1・Class1のように連番方式にせず、PixelData構造体・Imageクラスのように、わかりやすい名称をつけるようにしてください。
そうすることで、構造体やクラスの宣言ミスが少なくなるほか、可読性も上がるのでソースをトレースする際も見やすいはずです。