JavaScript EditorDhtml editor     Free javascript download 



Main Page

The syntax for conversion operators has changed from Managed Extensions for C++ to Visual C++ 2005.

Speaking of that grotty feel, having to write op_Implicit to specify a conversion just didn’t feel like C++ in Managed Extensions. For example, here is a definition of MyDouble taken from the language specification:

В CopyCode imageCopy Code
__gc struct MyDouble {
   static MyDouble* op_Implicit( int i ); 
   static int op_Explicit( MyDouble* val );
   static String* op_Explicit( MyDouble* val ); 
};

This says that, given an integer, the algorithm for converting that integer into a MyDouble is provided by the op_Implicit operator. Moreover, that conversion will be carried out implicitly by the compiler. Similarly, given a MyDouble object, the two op_Explicit operators provide the respective algorithms for converting that object into either an integer or a managed String entity. However, the compiler will not carry out the conversion unless explicitly requested by the user.

In C#, this would look as follows:

В CopyCode imageCopy Code
class MyDouble {
   public static implicit operator MyDouble( int i ); 
   public static explicit operator int( MyDouble val );
   public static explicit operator string( MyDouble val ); 
};

And apart from the weirdness of the explicit public access label for each member, the C# code looks a lot more like C++ than Managed Extensions for C++ does. So we had to fix that. But how should we do that?

On one hand, C++ programmers are left slightly reeling by the absence of a single argument constructor being construed as a conversion operator. On the other hand, however, that design proved grotty enough to manage that the ISO-C++ committee introduced a keyword, explicit, just to reign in its unintended consequences – for example, an Array class which takes a single integer argument as a dimension will implicitly convert any integer into an Array object even when that is the very last thing one wants. Andy Koenig was the first person who brought that to my attention when he explained a design idiom of a dummy second argument to a constructor just to prevent such a bad thing from happening. So I don’t regret the absence of a single constructor implicit conversion in the Visual C++ 2005 language.

On the other hand, it is not ever a good idea to provide a conversion pair when designing a class type within C++. The best example for that is the standard string class. The implicit conversion is the single-argument constructor taking a C-style string. However, it does not provide the corresponding implicit conversion operator – that of converting a string object to a C-style string, but rather requires the user to explicitly invoke a named function – in this case, c_str().

So, associating an implicit/explicit behavior on a conversion operator (as well as encapsulating the set of conversions to a single form of declaration) appears to be an improvement on the original C++ support for conversion operators, which has been a public cautionary tale back since 1988 when Robert Murray gave a Usenix C++ talk entitled "Building Well-Behaved Type Relationships in C++", and which eventually led to the explicit keyword. The Visual C++ 2005 language support for conversion operators looks as follows, which is slightly less verbose than that of C# due to the default behavior of the operator supporting an implicit application of the conversion algorithm:

В CopyCode imageCopy Code
ref struct MyDouble {
public:
   static operator MyDouble^ ( int i );
   static explicit operator int ( MyDouble^ val );
   static explicit operator String^ ( MyDouble^ val );
};

Another change is that a single argument constructor is treated as if it is declared as explicit. This means that in order to trigger its invocations, an explicit cast is required. Note, however, that if an explicit conversion operator is defined, it and not the single-argument constructor, is invoked.

See Also



JavaScript EditorDhtml editor     Free javascript download