2010-03-22

user-defined conversionは、何回適用されるのか

答え:一回。

struct X { operator int(){ return 0 ; } } ;
struct Y { operator X(){ return X() ; } } ;

int main()
{
    Y a;
    int b = a; // error
    // a.operator X().operator int() not tried
    int c = X(a); // OK: a.operator X().operator int()
}

なぜならば、12.3 Conversions [class.conv] p4に、"At most one user-defined conversion (constructor or conversion function) is implicitly applied to a single value."と書いてあるからだ。

なるほど、それはいい。というのも、変換関数が二回以上、暗黙的に呼び出されては、混乱の元だからだ。

上の例は、conversion functionを使っているが、constructorでも、同じだという。どれどれ。

struct Type1 {  } ;
struct Type2 { Type2(Type1) {} } ;
struct Type3 { Type3(Type2) {} } ;
struct Type4 { Type4(Type3) {} } ;

int main()
{
    Type2 t2 = Type1() ;// OK
    Type3 t3 = Type1() ;// error. VC accept it.(WRONG! Bad Compiler VC! You are a bad compiler!)
    Type4 t4 = Type1() ;// error. VC deny it correctly.
}

おい、VC。いい加減にせい。

2chのC++0xスレで、珍しく、C++の話題が論じられているので、ふと、user-defined conversionについて気になった。調べてみたところ、またVCの糞っぷりが明らかになった。

3 comments:

Anonymous said...

>Type3 t3 = Type1() ;

拡張機能を無効(/Za)にすれば、エラーになりますね。

Anonymous said...

> Type3 t3 = Type1() ;// error. VC accept it.(WRONG! Bad Compiler VC! You are a bad compiler!)
拡張機能を無効(/Za)にすればエラーになりますね。

江添亮 said...

お、無効にできた。
なるほど。そんなオプションが。