C++/CX factory class to provide overloaded constructors with same number of arguments

391 views Asked by At

I am new to C++/CX, IDL and WRL, and ran into a problem I am not sure if there is error in my code or it is the limitation of the design.

I have an IDL that defines an IInspectable interface and its runtimeclass, along with a factory class that can provide custom constructor. The file looks like something like this:

interface IFoo;    
runtimeclass Foo;
interface IFooFactory;    
[uuid(8543FE719-3F40-987B-BB67-6FD499210BCA), version(0.1), exclusiveto(Foo)]    
interface IFooFactory : IInspectable    
{        
    HRESULT CreateInt32Instance([in] __int32 value, [out][retval]Foo **ppFoo);
    HRESULT CreateInt64Instance([in] __int64 value, [out][retval]Foo **ppFoo);
}    

[uuid(23017380-9876B-40C1-A330-9B6AE1263F5E), version(0.1), exclusiveto(Foo)]
interface IFoo : IInspectable    
{
    HRESULT GetAsInt32([out][retval] __int32 * value);
    HRESULT GetAsInt64([out][retval] __int64 * value);
}

[version(0.1), activatable(0.1), activatable(IFooFactory, 0.1)]    
runtimeclass Foo
{
    [default] interface IFoo;
}

The code itself is trivial, the key part is that in the definition of IFooFactory, I have two functions that will be projected to constructors for class Foo. Those two functions have same number of arguments but different types.

When I try to compile this IDL, the compiler complains that:

More than one factory method with same number of arguments in the projected constructors.

I've been searching on the Internet for quite sometime but couldn't find anything that mentions this kind of problem. Is overloaded constructors with same number of arguments not allowed in this situation? If it is allowed, how should I modify this IDL? If not, is there any work around I can use?

1

There are 1 answers

1
Raymond Chen On BEST ANSWER

Overloaded constructors with same number of arguments are not allowed because dynamically-typed languages (such as JavaScript) would not know which constructor to use.

The standard approach is to use named static methods.

[uuid(....), version(...), exclusiveto(Foo)]
interface IFooStatics : IInspectable    
{        
    HRESULT FromInt32([in] INT32 value, [out, retval] Foo** result);
    HRESULT FromInt64([in] INT64 value, [out, retval] Foo** result);
}

[version(...)]
/* not activatable */
[static(IFooStatics)]
runtimeclass Foo
{
    [default] interface IFoo;
}

You would then say

// C++
Foo^ foo1 = Foo::FromInt32(int32Variable);
Foo^ foo2 = Foo::FromInt64(int64Variable);

// C#
Foo foo1 = Foo.FromInt32(int32Variable);
Foo foo2 = Foo.FromInt64(int64Variable);

// JavaScript
var foo1 = Foo.fromInt32(var1);
var foo2 = Foo.fromInt64(var2);