2014-04-02 50 views
1

我正在遷移VS2008 (VC++)代碼到VS2013。我得到以下錯誤:錯誤C2664:無法將參數2從'const ATL :: CAdapt <ATL :: CComPtr <IZipFileEntry >> *'轉換爲'ATL :: CAdapt <ATL :: CComPtr <IZipFileEntry >> *'

error C2664: 'HRESULT _CopyItfFromAdaptItf<IZipFileEntry>::copy(T **,ATL::CAdapt<ATL::CComPtr<T>> *)' : cannot convert argument 2 from 'const ATL::CAdapt<ATL::CComPtr<IZipFileEntry>> *' to 'ATL::CAdapt<ATL::CComPtr<IZipFileEntry>> *' 

錯誤出現在Visual Studio SDK文件中,它怎麼可能?我無法修復這個錯誤。請在下面的輸出和錯誤行下面找到。

非常感謝您的幫助!

輸出:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\atlmfc\include\atlcom.h(5818): error C2664: 'HRESULT _CopyItfFromAdaptItf<IZipFileEntry>::copy(T **,ATL::CAdapt<ATL::CComPtr<T>> *)' : cannot convert argument 2 from 'const ATL::CAdapt<ATL::CComPtr<IZipFileEntry>> *' to 'ATL::CAdapt<ATL::CComPtr<IZipFileEntry>> *' 
     with 
     [ 
      T=IZipFileEntry 
     ] 
     Conversion loses qualifiers 
     C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\atlmfc\include\atlcom.h(5803) : while compiling class template member function 'HRESULT ATL::ICollectionOnSTLImpl<IZipFileDir1,EntryList,IZipFileEntry *,_CopyItfFromAdaptItf<IZipFileEntry>,EntryEnum>::get_Item(long,ItemType *)' 
     with 
     [ 
      ItemType=IZipFileEntry * 
     ] 
     C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\atlmfc\include\atlcom.h(5140) : see reference to class template instantiation 'ATL::ICollectionOnSTLImpl<IZipFileDir1,EntryList,IZipFileEntry *,_CopyItfFromAdaptItf<IZipFileEntry>,EntryEnum>' being compiled 

錯誤代碼:

if (iter != m_coll.end()) 
     hr = CopyItem::copy(pvar, &*iter); // Error C2664 
return hr; 

P.S:我不能夠編輯並保存此文件atlcom.h。我得到路徑被拒絕的錯誤信息。這是因爲它的SDK文件?

一些更多的代碼定義補充說:

struct _CopyItfFromAdaptItf { 
    static HRESULT copy(T** p1, CAdapt< CComPtr<T> >* p2) { 
    if(*p1 = p2->m_T) return (*p1)->AddRef(), S_OK; 
    return E_POINTER; 
} 


IZipFileEntry : public IDispatch 
{ 
    public: 
     virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_name( 
     /* [retval][out] */ BSTR *pVal) = 0; 

     virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_lastModified( 
     /* [retval][out] */ DATE *pVal) = 0; 

     virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_fileSize( 
     /* [retval][out] */ long *pVal) = 0; 

     virtual /* [helpstring][id][propget] */ HRESULT STDMETHODCALLTYPE get_compressedSize( 
     /* [retval][out] */ long *pVal) = 0; 

    }; 


typedef ICollectionOnSTLImpl<IZipFileDir1, EntryList, IZipFileEntry*, _CopyItfFromAdaptItf<IZipFileEntry>, EntryEnum> EntryCollection; 

ICollectionOnSTLImpl的定義

class ICollectionOnSTLImpl : 
    public T 
{ 
public: 
     STDMETHOD(get_Count)(_Out_ long* pcount) 
     { 
     if (pcount == NULL) 
      return E_POINTER; 
     ATLASSUME(m_coll.size()<=LONG_MAX); 

     *pcount = (long)m_coll.size(); 

     return S_OK; 
    } 
    STDMETHOD(get_Item)(
     _In_ long Index, 
     _Out_ ItemType* pvar) 
    { 
     //Index is 1-based 
     if (pvar == NULL) 
      return E_POINTER; 
     if (Index < 1) 
      return E_INVALIDARG; 
     HRESULT hr = E_FAIL; 
     Index--; 
     CollType::const_iterator iter = m_coll.begin(); 
     while (iter != m_coll.end() && Index > 0) 
     { 
      iter++; 
      Index--; 
     } 
     if (iter != m_coll.end()) 
      hr = CopyItem::copy(pvar, &*iter); 
     return hr; 
    } 
    STDMETHOD(get__NewEnum)(_Outptr_ IUnknown** ppUnk) 
    { 
     if (ppUnk == NULL) 
      return E_POINTER; 
     *ppUnk = NULL; 
     HRESULT hRes = S_OK; 
     CComObject<EnumType>* p; 
     hRes = CComObject<EnumType>::CreateInstance(&p); 
     if (SUCCEEDED(hRes)) 
     { 
      hRes = p->Init(this, m_coll); 
      if (hRes == S_OK) 
       hRes = p->QueryInterface(__uuidof(IUnknown), (void**)ppUnk); 
     } 
     if (hRes != S_OK) 
      delete p; 
     return hRes; 
    } 
    CollType m_coll; 
}; 
+0

是的,它是因爲它的SDK文件,你絕對不應該改變它們。您顯然將一個指向const變量的指針提供給想要更改所述變量的函數。仔細查看模板錯誤,直到找到導致問題的代碼行。模板錯誤是最糟糕的解密解釋了爲什麼ATL是如此煩人;) – Muepe

+0

它說,代碼行試圖寫入一個你不應該寫的地方。這可能是對的。 – Yakk

+0

其實我收到一條錯誤消息,指出「atlimpl.cpp」未找到/無法打開。根據以下鏈接中的建議,http://social.msdn.microsoft.com/Forums/en-US/4117ea1a-23a9-4b57-a753-547f9fc1087b/statregcpp-atlimplcpp-is-obsolete?論壇= vcgeneral,我評論#包括線,然後在構建我得到這個錯誤。懷念#include 是不正確的? – user3360310

回答

2

很難肯定地說沒有所有的代碼,但它看起來像我有以下問題再次出現,代碼:

template<class T> 
struct _CopyItfFromAdaptItf { 
    static HRESULT copy(T** p1, CAdapt< CComPtr<T> >* p2) { 
     if(*p1 = p2->m_T) return (*p1)->AddRef(), S_OK; 
     return E_POINTER; 
    } 
}; 

IDispatch** disp; 
const CAdapt<CComPtr<IDispatch>> adapt; // note const here 
_CopyItfFromAdaptItf<IDispatch>::copy(disp, &adapt); //error C2664 here 

編譯器輸出爲

File(Line) : error C2664: '_CopyItfFromAdaptItf<T>::copy' : 
    cannot convert parameter 2 from 'const ATL::CAdapt<T> *' to 'ATL::CAdapt<T> *' 
    with 
    [ 
     T=IDispatch 
    ] 
    and 
    [ 
     T=ATL::CComPtr<IDispatch> 
    ] 
    and 
    [ 
     T=ATL::CComPtr<IDispatch> 
    ] 
    Conversion loses qualifiers 

它幾乎與您引用的輸出相匹配。

問題是_CopyItfFromAdaptItf::copy()想要一個指向非const的指針,但是傳遞了一個指向const的指針。傳遞給const的指針的代碼位於屬於SDK頭文件的atlcom.h中,因此最好不要更改它。

此外,如果_CopyItfFromAdaptItf::copy()簽名更改爲接受指針常量:

static HRESULT copy(T** p1, const CAdapt< CComPtr<T> >* p2) // note addition of const 

它仍然編譯就好了。 _CopyItfFromAdaptItf在ATL頭文件中沒有地方,所以我想它在你的代碼中,你可以改變它。

所以看起來像解決的辦法是簡單地改變_CopyItfFromAdaptItf::copy()接受一個指向const的指針,問題就會消失。

+0

您的解決方案修復了錯誤。感謝你的努力和時間。非常感謝!!! – user3360310

相關問題