Ultimately the solution was described by igor tandetnik in the comments above:
Basically in VC2010+ ATL::CComPtr
has a sizeof
that is the same as the pointer they represent (e.g. sizeof(ATL::CComPtr<IWICColorContext>) == sizeof(IWICColorContext*)
), as best I can tell this is because they have no virtual functions and thus need no vTable. This is however highly dangerous as it's relying on a compiler implementation detail. Thus the following works:
std::vector<ATL::CComPtr<IWICColorContext> > > vec(5);
// CComPtrs are created and initialized here
GetColorContexts(vec.size(), &vec[0].m_T, ...);
Mark brought up a very good point that the solution above was completely dependent on compiler implementation which is dangerous. However the solution of only attaching ATL::CComPtr
after the GetColorContexts
call was not palattable either as it would not have been exception safe.
Ultimately my solution (tested this morning) is to create a vector<IWICColorContext*>
temporarily from the vector<CComPtr<IWICColorContext>>
this temporary vector
does not increment the ref count and allows me to maintain exception safety.