Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C2594 : Ambiguous Conversion with COM Object

Tags:

c++

com

atl

I have an ATL class that I'm trying to implement a cast operator for each interface that it implements. The class is a mock representing a real object.

class CMock :
  public IDispatchImpl<Interface1 ...>
  public IDispatchImpl<Interface2 ...>

The ATL COM Mapping is as follows:

BEGIN_COM_MAP(CMock)
  // Resolve ambiguity by exposing Interface1 through Interface2
  COM_INTERFACE_ENTRY2(Interface1, Interface2)
  COM_INTERFACE_ENTRY(Interface)
END_COM_MAP()

I then have overloaded the cast operators for Interface1* and Interface2*

operator Interface1* () 
{ 
  Interface1* pInterface1;
  if(FAILED(this->QueryInterface(IID_Interface1, reinterpret_cast<void**>(&pInterface1)))
     return nullptr;
  return pInterface1;
}
// Repeat for IInterface2

Despite the overloaded cast operators, I'm still getting an ambiguous error when trying to cast to any interface that is exposed through another.

error C2594: 'argument' : ambiguous conversions from 'CMock *' to 'Interface1 *'

int main()
{
   CComPtr<CMock> mock = new CComObject<CMock>();

   Interface1* pInterface1 = mock; // Error C2594
   Interface2* pInterface2 = mock; // compiles OK.
   return 0;
}

I understand WHY the ambiguous conversions are there, but I'm confused as to why the compiler is even looking at those when I define a custom cast operator. Is there anyway to define the cast operator such that the compiler will ignore the other conversion possibilities?

like image 605
lcs Avatar asked Dec 09 '25 21:12

lcs


1 Answers

Your defining cast operator does not help here since you are defining it on CMock class, while the problem happens with CComPtr<CMock>, which is a wrapper on top of CMock*. So the operator is not helpful, however it does not need to help.

Skipping other issues in your snippets (and there are a few of them), you eventually need the following:

If you have a raw pointer, such as CMock* or CComObject<CMock>* then you can cast using C++ cast operators, e.g.

Interface1* pInterface1 = (Interface*) (CMock*) mock;

If you have an interface pointer of your object, not the native pointer, then you can get your interface using QueryInterface or CComQIPtr.

CComQIPtr<Interface1> pInterface1 = mock; // or, "... = (Interface2*) mock;"
                                 // to possibly resolve `IUnknown*` ambiguities
like image 92
Roman R. Avatar answered Dec 11 '25 11:12

Roman R.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!