http://www.kuzbass.ru:8086/docs/isocpp/special.html#class.conv
ã¯ã©ã¹ã®åå¤æã¯ã³ã³ã¹ãã©ã¯ã¿ã¨åå¤æé¢æ°ã使ã£ã¦å®ç¾©ã§ããããããã®åå¤æã¯ãã¦ã¼ã¶ã¼å®ç¾©åå¤æã¨å¼ã°ããæé»çåå¤æãå¤æ°åæååãæ示çåå¤æã«ä½¿ãããã
ã¦ã¼ã¶ã¼å®ç¾©åå¤æã¯ãåå¤æã®å®ç¾©ãææ§ãããªãã¨ãã«ã ãé©ç¨ããããåå¤æã¯ãã¢ã¯ã»ã¹å¶å¾¡è¦åï¼private, public, protectedï¼ã«å¾ããã¢ã¯ã»ã¹å¶å¾¡è¦åã¯ãææ§ãã®è§£æ±ºã®ãã¨é©ç¨ãããã
ãã£ã¨ã使ãããã¦ã¼ã¶ã¼å®ç¾©åå¤æã¯ãåä¸å¤ã¸ã®æé»çåå¤æã ã
class X { // ... public: operator int(); }; class Y { // ... public: operator X(); }; Y a; int b = a; // NG: X().operator int() ã¯å¼ã°ããªã int c = X(a); // OK: X().operator int() ãå¼ã°ãã
ã¦ã¼ã¶ã¼å®ç¾©åå¤æã¯ãææ§ã§ãªãã¨ãã«ã ãæé»çåå¤æã§ä½¿ããããåã¯ã©ã¹ã®åå¤æé¢æ°ã§è¦ªã¯ã©ã¹ã®ä»ã®åã¸ã®åå¤æé¢æ°ãé ããã¨ã¯ã§ããªããé¢æ°ãªã¼ãã¼ãã¼ã解決ï¼すごいややこしいï¼ã«ãã£ã¦ãæé©ãªå¤æé¢æ°ãé¸æãããï¼ãã®çµæãææ§ã¨å¤æãããå¯è½æ§ãããï¼ã
class X { public: // ... operator int(); }; class Y : public X { public: // ... operator char(); }; void f(Y& a) { if (a) { // NG: Y ã«ã¯ int 㨠char ã¸ã®ã¦ã¼ã¶ã¼å®ç¾©åå¤æãå®ç¾©ããã¦ããã®ã§ãææ§ } }
ã³ã³ã¹ãã©ã¯ã¿ã«ããåå¤æ
explicit ãªãã® 1 åã®å¼æ°ã§ãã³ã ããã³ã³ã¹ãã©ã¯ã¿ã®å®ç¾©ã¯ããã®å¼æ°ã®åããããã®ã¯ã©ã¹åã¸ã®åå¤æãå®ç¾©ããããã®ãããªã³ã³ã¹ãã©ã¯ã¿ãåå¤æã³ã³ã¹ãã©ã¯ã¿ã¨å¼ã¶ã
class X { // ... public: X(int); X(const char*, int =0); }; void f(X arg) { X a = 1; // a = X(1) X b = "Jessie"; // b = X("Jessie",0) a = 2; // a = X(2) f(3); // f(X(3)) }
explicit æãã®ã³ã³ã¹ãã©ã¯ã¿ã¯ãå¤æ°ã®ç´æ¥åæåãæ示çãã£ã¹ãããåºæ¥ãªãã
class Z { public: explicit Z(); explicit Z(int); // ... }; Z a; // OK: ç´æ¥åæå Z a1 = 1; // NG: æé»çåå¤æ Z a3 = Z(1); // OK: ç´æ¥åæå Z a2(1); // OK: ç´æ¥åæå Z* p = new Z(1); // OK: ç´æ¥åæå Z a4 = (Z)1; // OK: æ示çãã£ã¹ã Z a5 = static_cast<Z>(1); // OK: æ示çãã£ã¹ã
ã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¯åå¤æã³ã³ã¹ãã©ã¯ã¿ã ãæé»çã«å®ç¾©ãããã³ãã¼ã³ã³ã¹ãã©ã¯ã¿ã¯ã explicit ãªã³ã³ã¹ãã©ã¯ã¿ã§ã¯ãªãã®ã§ãæé»çåå¤æã«ä½¿ãäºãã§ããã
åå¤æé¢æ°
ããã¯ã©ã¹ X ã®ä»¥ä¸ã®ãããªååã®ã¡ã³ãé¢æ°ã¯ã
conversion-function-id: operator conversion-type-id conversion-type-id: type-specifier-seq conversion-declaratoropt conversion-declarator: ptr-operator conversion-declaratoropt
X ãã conversion-type-id ã¸ã®åå¤æãå®ç¾©ããããã®ãããªã¡ã³ãé¢æ°ãåå¤æé¢æ°ã¨å¼ã¶ãå¼æ°ã¨æ»ãå¤ãå®ç¾©ããªããåå¤æé¢æ°ã®åã¯ãå¼æ°ç¡ã㧠conversion-type-id ãè¿ãã¡ã³ãé¢æ°ã®åã¨ãªããåå¤æé¢æ°ã¯ãåãåã®ãªãã¸ã§ã¯ãå士ã®å¤æã親ã¯ã©ã¹ããã®å¤æã void ã¸ã®å¤æã«ã¯ä½¿ãããªã
class X { // ... public: operator int(); }; void f(X a) { int i = int(a); i = (int)a; i = a; }
é¢æ° f å
ã®ãã¹ã¦ã®æã§åå¤æé¢æ° X::operator int() ã«ããåå¤æãè¡ããã
ã¦ã¼ã¶ã¼å®ç¾©åå¤æã¯ãå¤æ°åæåæã代å
¥æã§ãã使ãããªãã¨ãããã¨ã¯ãªããï¼ä¾ãã°ã if ããä¸é
æ¼ç®åã®æ¡ä»¶é¨ãã && ã®ãªãã©ã³ãï¼
void g(X a, X b) { int i = (a) ? 1+a : 0; int j = (a&&b) ? a+b : i; if (a) { // ... } }
The conversion-type-id shall not represent a function type nor an array type. The conversion-type-id in a conversion-function-id is the longest possible sequence of conversion-declarators.
This prevents ambiguities between the declarator operator * and its expression counterparts.
&ac.operator int*i; // syntax error: // parsed as: &(ac.operator int *) i // not as: &(ac.operator int)*i
The * is the pointer declarator and not the multiplication operator.
Conversion functions are inherited.
Conversion functions can be virtual.