アプリ版:「スタンプのみでお礼する」機能のリリースについて

下記プログラムを実行した時の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; }

どなたか詳しい方、ご教授の程よろしくお願い致します。

A 回答 (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以外を削除すれば、これまた
エラーなしで実行できるようになります。(多分
    • good
    • 0
この回答へのお礼

丁寧な解説ありがとうございました。
おかげさまですっきりしました。

お礼日時:2011/05/14 13:00

ちなみに (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を定義してやれば、特に問題はないのですが
不思議でなりません。。。

補足日時:2011/05/12 21:26
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!