下記プログラムを実行した時のoperator演算子の動作についての質問になります。
(VC++2010で動作確認)
#include <iostream>
struct UInterger
{
unsigned long ul_ui;
UInterger( unsigned long ul_value ) : ul_ui( ul_value ) {}
operator unsigned short() { return (unsigned short)ul_ui; } //(1)の時になぜ使用される?.
operator unsigned int() { return (unsigned int)ul_ui; }
operator unsigned long() { return (unsigned long)ul_ui; }
};
int main()
{
UInterger s_uin(2);
int i_temp = s_uin; // (1)コンパイルが通る.
short s_temp = s_uin; // (2)コンパイルエラー.
long l_temp = s_uin; // (3)コンパイルエラー.
return 0;
}
(2)と(3)はoperatorの定義がないためコンパイルエラーとなるのは理解できます。
(1)でなぜコンパイルが通るのかがわかりません。
下記の定義を追加しない限り、コンパイルは通らないのではと考えております…
operator int() { return (int)ul_ui; }
試しに(2)と(3)をコメントアウトしてステップ実行したところ
(1)の時に下記のunsigned short()のオペレータが使用されておりました。
operator unsigned short() { return (unsigned short)ul_ui; }
どなたか詳しい方、ご教授の程よろしくお願い致します。
No.1
- 回答日時:
ちなみに (2) と (3) のエラーメッセージは出せますか?
この回答への補足
エラーメッセージですが以下になります。(VC++2010で確認)
(2)
error C2440: '初期化中' : 'UInterger' から 'short' に変換できません。
あいまいなユーザー定義変換です。
(3)
error C2440: '初期化中' : 'UInterger' から 'long' に変換できません。
あいまいなユーザー定義変換です。
VC6.0が入ってる別PCでやっても同じ結果になりました。
ちなみに(1)ですが、下記のint型のoperatorを追加して実行したら
unsigned short型のほうではなく下記のint型のほうを通っていました。
operator int() { return (int)ul_ui; }
ですので各型のoperatorを定義してやれば、特に問題はないのですが
不思議でなりません。。。
No.2ベストアンサー
- 回答日時:
間違っていたらすみません。
私の理解だと次の通りです。型変換の優先度は、次の通りです。
1. 型変換不要
2. 汎整数拡張 (演算時に、intより小さい変数が勝手にintに拡張されること)
3. 型変換
これを元に解説すると、
(1). intに対する代入なので、
1. operator intを探す
2. 汎整数拡張できる、intより小さい変数型へのoperatorを探す
3. その他型変換できる変数型へのoperatorを探す
という順番で解釈されます。
1.は無いので×
2.で、unsigned short型へのoperatorが見つかるので、採用する。
というわけで、(1).はunsigned shortへのoperatorになります。
(2). shortに対する代入なので、
1. operator short を探す
2. その他型変換できる変数型へのoperatorを探す
という順番で解釈されるので、
1. は無いので×
2.で、unsigned short型, unsigned long型, unsigned int型へのoperatorがそれぞれ見つかるため、
どれを採用すればいいか、わからないのでエラー
ということになります。
(3). も、(2)と同じです。
以下、余談です。
質問者さんは、(2),(3),で、1.の内容を実装することでエラーなしで実行できることを確認されたと思います。
逆に、2.で採用されるものを一つに限定する、すなわちoperator unsigned short以外を削除すれば、これまた
エラーなしで実行できるようになります。(多分
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- C言語・C++・C# C++初心者です stirng 2 2022/09/20 20:43
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- その他(プログラミング・Web制作) pythonリストの特定の値を表示htmlで表示できない 2 2022/05/14 05:48
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エラー「invalid conversion fr...
-
DWORDの実際の型は何でしょうか
-
相互参照するクラス、俺こんな...
-
構造体の要素すべてに対する四...
-
【#define】 defineで定義した...
-
long型の定数の末尾にLを付ける...
-
構造体を引数とする、クラス間...
-
C言語のreturnの使い方
-
構造体の宣言でエラーが出ます。
-
typedef enumの使い方を教えて...
-
0除算を判定したい
-
不正な構造体の演算
-
C言語でのフィボナッチ数列の表示
-
変数の型を定義しなかった場合...
-
2÷3などの余りについて
-
Enterキーを押されたら次の処理...
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語を実行すると-infが出てき...
-
std::set<int> で、ある値が何...
-
Aの値からBの値を除するとは??
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
DWORDの実際の型は何でしょうか
-
typedef enumの使い方を教えて...
-
C++のfor文について
-
long型の定数の末尾にLを付ける...
-
2重定義って??
-
関数の実体定義にヘッダファイ...
-
main.c:7:43: warning: implici...
-
変数の型を定義しなかった場合...
-
visualstudio C# テキストボッ...
-
ハンドルされていない例外が発...
-
C++でboolにintの値を代入する...
-
enumについて
-
構造体の宣言でエラーが出ます。
-
【#define】 defineで定義した...
-
C++ クラスをメンバにもつクラ...
-
0除算を判定したい
-
構造体の要素すべてに対する四...
-
値を返り値に返すのと参照渡し...
-
namespace定義の使い方
-
GCCで暗黙の型変換の警告を出し...
おすすめ情報