Error C2385 on (ctor)

P

PLS

I'm converting some C++ code to VC++ 2005 in native (non-managed) mode.
This code doesn't use ATL, but codes the COM mechanisms directly.

It has a class which is the equivalent of ATL's IDispatchImpl:

template<class T>
class CDispatch : virtual public IDispatch, virtual public CUnknown,
private CDispatchBase
{
...

CDispatch::CDispatch(IUnknown *pOuterUnknown)
: CUnknown(pOuterUnknown),
m_pITypeInfo(0)
{}

...
};

The constructor produces this error:

c:\project\pciw\cdisp.h(253) : error C2385: ambiguous access of '{ctor}'
could be the '{ctor}' in base 'IDispatch'
or could be the '{ctor}' in base 'CUnknown'
or could be the '{ctor}' in base 'CDispatchBase'
c:\project\pciw\cdisp.h(285) : see reference to class template
instantiation 'CDispatch<T>' being compiled


I understand about name collisions and disambiguation for methods in
multiple inheritance. How do you disambiguate a constructor?

Seriously, how do I fix this?

Thanks,
++PLS
 
V

Vladimir Nesterovsky

1. Is it correct that CDispatchBase inherits CUnknown (non virtually)? Is it
your intention?
2. Can you define CDispatch constructor this way:

CDispatch::CDispatch(IUnknown *pOuterUnknown)
: CDispatch::CUnknown(pOuterUnknown),
m_pITypeInfo(0)
{}

?

I'm converting some C++ code to VC++ 2005 in native (non-managed) mode.
This code doesn't use ATL, but codes the COM mechanisms directly.

It has a class which is the equivalent of ATL's IDispatchImpl:

template<class T>
class CDispatch : virtual public IDispatch, virtual public CUnknown,
private CDispatchBase
{
...

CDispatch::CDispatch(IUnknown *pOuterUnknown)
: CUnknown(pOuterUnknown),
m_pITypeInfo(0)
{}

...
};

The constructor produces this error:

c:\project\pciw\cdisp.h(253) : error C2385: ambiguous access of '{ctor}'
could be the '{ctor}' in base 'IDispatch'
or could be the '{ctor}' in base 'CUnknown'
or could be the '{ctor}' in base 'CDispatchBase'
c:\project\pciw\cdisp.h(285) : see reference to class template
instantiation 'CDispatch<T>' being compiled


I understand about name collisions and disambiguation for methods in
multiple inheritance. How do you disambiguate a constructor?


Thanks.
 
P

PLS

Changing the constructor as you suggest gives exactly the same error.
And I get that error without the virtuals in the class declaration.

CDispatchBase has no base classes.

IDispatch has IUnknown as a base class.

CUnknown has IUnknown as a base class.

And removing CUnknown and "virtual" from the CDisp base classes gives a
very similar error message:
c:\project\pciw\cdisp.h(253) : error C2385: ambiguous access of '{ctor}'
could be the '{ctor}' in base 'IDispatch'
or could be the '{ctor}' in base 'CDispatchBase'
c:\project\pciw\cdisp.h(284) : see reference to class template
instantiation 'CDispatch<T>' being compiled

I'm stumped. It looks like C++ 2005 just can't handle multiple
inheritance. Any base class is going to have a constructor.

++PLS
 
B

Ben Voigt

PLS said:
Changing the constructor as you suggest gives exactly the same error.
And I get that error without the virtuals in the class declaration.

CDispatchBase has no base classes.

IDispatch has IUnknown as a base class.

CUnknown has IUnknown as a base class.

And removing CUnknown and "virtual" from the CDisp base classes gives a
very similar error message:
c:\project\pciw\cdisp.h(253) : error C2385: ambiguous access of '{ctor}'
could be the '{ctor}' in base 'IDispatch'
or could be the '{ctor}' in base 'CDispatchBase'
c:\project\pciw\cdisp.h(284) : see reference to class template
instantiation 'CDispatch<T>' being compiled

I'm stumped. It looks like C++ 2005 just can't handle multiple
inheritance. Any base class is going to have a constructor.

Have you tried the Comeau online compiler? If it accepts the code then
Visual C++ definitely has a bug. If not, it may yield a much clearer error
message.
 
P

PLS

Comeau online compiler
Actually, that helped. Thank you.

Here's what the problem is:

template<class T>
class CDispatch : virtual public IDispatch, virtual public CUnknown,
private CDispatchBase
{
...

CDispatch::CDispatch(IUnknown *pOuterUnknown)
: CUnknown::CUnknown(pOuterUnknown),
m_pITypeInfo(0)
{}


CDispatch::~CDispatch()
{
if (m_pITypeInfo != NULL)
{
m_pITypeInfo->Release();
}
}

...
};

The Comeau compiler tells me:
"ComeauTest.c", line 379: error: qualified name is not allowed in member
declaration
CDispatch::CDispatch(IUnknown *pOuterUnknown)

Remove the "CDispatch::" from these two methods and everything works.

I guess this is a restriction in the new C++ standard. Can anyone
confirm this?

I think this is a compiler bug, because of the horribly off target
message. Can anyone tell me how to file a bug report?

Thanks,
++PLS
 
B

Ben Voigt

PLS said:
Actually, that helped. Thank you.

Here's what the problem is:

template<class T>
class CDispatch : virtual public IDispatch, virtual public CUnknown,
private CDispatchBase
{
...

CDispatch::CDispatch(IUnknown *pOuterUnknown)
: CUnknown::CUnknown(pOuterUnknown),
m_pITypeInfo(0)
{}


CDispatch::~CDispatch()
{
if (m_pITypeInfo != NULL)
{
m_pITypeInfo->Release();
}
}

...
};

The Comeau compiler tells me:
"ComeauTest.c", line 379: error: qualified name is not allowed in member
declaration
CDispatch::CDispatch(IUnknown *pOuterUnknown)

Oh, your functions are defined inside the class declaration block,
definitely you shouldn't double up the class name.
Remove the "CDispatch::" from these two methods and everything works.

I guess this is a restriction in the new C++ standard. Can anyone
confirm this?

I think you were instructing the compiler to look for a nested class.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top