There was a very interesting thread on Code Project’s C++/CLI forum last week. Here’s the link to the thread :
The gist of the post is that the C++/CLI compiler was not recognizing an overloaded unary operator defined in an interface while it could do so when the interface was changed to a base class.
Here’s some example code that reproduces the problem :
interface class Base
{
public:
static int operator * (Base^) { return 99; }
static int operator + (Base^) { return 99; }
};
ref class Derived : Base
{
};
static void Foo()
{
Derived^ d = gcnew Derived();
int x = *d;
int y = +d;
Both those lines will not compile. In the case of the * operator you get a confusing error because the compiler assumes you are trying to dereference the handle.
Error 1 error C2440: 'initializing' : cannot convert from
'Test::Derived' to 'int'
Error 2 error C2675: unary '+' : 'Test::Derived ^' does not define this
operator or a conversion to a type acceptable to the predefined
operator
Changing Base from an interface class to a ref class works fine. I believe this is a compiler bug because the ECMA language specification says this in section 25.2 Interface members:
“An interface definition can declare zero or more members. The members of an interface shall be static data members, instance or static functions, a static constructor, instance or static properties, instance or static events, operator functions, or nested types of any kind. An interface shall not contain instance data members, instance constructors, or a finalizer.”
The workaround right now is to do this :
int x = Base::operator *(d);
int y = Base::operator +(d);
Affected versions:
This bug exists in VS 2008 as well as in VS 2010 RC.
Read Full Post »