2010-04-15 92 views
0

我有一些編譯和運行在MSVC++上的代碼,但不會在GCC上編譯。我做了一個測試片段。我的目標是將靜態方法從BFSMask移到BFSMaskSized。有人可以解釋錯誤發生了什麼(特別是奇怪的'運營商<'錯誤)?謝謝。GCC在模板父類中調用靜態模板函數的問題

如果兩個#defines都是0,那麼代碼會在GCC上編譯。

#define DOESNT_COMPILE_WITH_GCC  0 
#define FUNCTION_IN_PARENT   0 

如果我將#define更改爲1,則會出現錯誤。下面是我看到的錯誤。

#define DOESNT_COMPILE_WITH_GCC  0 
#define FUNCTION_IN_PARENT   1 
Test.cpp: In static member function 'static typename Snapper::BFSMask<T>::T_Parent::T_SINT Snapper::BFSMask<T>::Create_NEZ(TCMP)': 
Test.cpp(492): error: 'CreateMaskFromHighBitSized' was not declared in this scope 

#define DOESNT_COMPILE_WITH_GCC  1 
#define FUNCTION_IN_PARENT   0 
Test.cpp: In static member function 'static typename Snapper::BFSMask<T>::T_Parent::T_SINT Snapper::BFSMask<T>::Create_NEZ(TCMP) [with TCMP = int, T = int]': 
Test.cpp(500): instantiated from 'TVAL Snapper::BFWrappedInc(TVAL, TVAL, TVAL) [with TVAL = int]' 
Test.cpp(508): instantiated from here 
Test.cpp(490): error: invalid operands of types '<unresolved overloaded function type>' and 'unsigned int' to binary 'operator<' 

#define DOESNT_COMPILE_WITH_GCC  1 
#define FUNCTION_IN_PARENT   1 
Test.cpp: In static member function 'static typename Snapper::BFSMask<T>::T_Parent::T_SINT Snapper::BFSMask<T>::Create_NEZ(TCMP) [with TCMP = int, T = int]': 
Test.cpp(500): instantiated from 'TVAL Snapper::BFWrappedInc(TVAL, TVAL, TVAL) [with TVAL = int]' 
Test.cpp(508): instantiated from here 
Test.cpp(490): error: invalid operands of types '<unresolved overloaded function type>' and 'unsigned int' to binary 'operator<' 

下面是代碼

namespace Snapper 
{ 
#define DOESNT_COMPILE_WITH_GCC  0 
#define FUNCTION_IN_PARENT   0 

    // MASK TYPES 
    // NEZ - Not Equal to Zero 
    #define BFSMASK_NEZ(A)  ((A) | (0 - A)) 
    #define BFSELECT_MASK(MASK,VTRUE,VFALSE) (((MASK)&(VTRUE)) | ((~(MASK))&(VFALSE))) 
    template<typename TVAL> TVAL BFSelect_MASK(TVAL MASK,TVAL VTRUE,TVAL VFALSE) 
    { return(BFSELECT_MASK(MASK,VTRUE,VFALSE)); } 

    //----------------------------------------------------------------------------- 
    // Branch Free Helpers 

    template<int BYTESIZE> struct BFSMaskBase {}; 
    template<> struct BFSMaskBase<2> 
    { 
     typedef UINT16 T_UINT; 
     typedef SINT16 T_SINT; 
    }; 
    template<> struct BFSMaskBase<4> 
    { 
     typedef UINT32 T_UINT; 
     typedef SINT32 T_SINT; 
    }; 
    template<int BYTESIZE> struct BFSMaskSized : public BFSMaskBase<BYTESIZE> 
    { 
     static const int SizeBytes  = BYTESIZE; 
     static const int SizeBits  = SizeBytes*8; 
     static const int MaskShift  = SizeBits-1; 
     typedef typename BFSMaskBase<BYTESIZE>::T_UINT  T_UINT; 
     typedef typename BFSMaskBase<BYTESIZE>::T_SINT  T_SINT; 

#if FUNCTION_IN_PARENT 
     template<int N> static T_SINT CreateMaskFromHighBitSized(typename BFSMaskBase<N>::T_SINT inmask); 
#endif 
    }; 

    template<typename T> struct BFSMask : public BFSMaskSized<sizeof(T)> 
    { 
     // BFSMask = -1 (all bits set) 

     typedef BFSMask<T>      T_This; 
     // "Import" the Parent Class 
     typedef BFSMaskSized<sizeof(T)>   T_Parent; 
     typedef typename T_Parent::T_SINT  T_SINT; 

#if FUNCTION_IN_PARENT 
     typedef T_Parent T_MaskGen; 
#else 
     typedef T_This  T_MaskGen; 
     template<int N> static T_SINT CreateMaskFromHighBitSized(typename BFSMaskSized<N>::T_SINT inmask); 
#endif 

     template<typename TCMP> static T_SINT Create_NEZ(TCMP A) 
     { 
      //ReDefineType(const typename BFSMask<TCMP>::T_SINT,SA,A); 
      //const typename BFSMask<TCMP>::T_SINT cmpmask = BFSMASK_NEZ(SA); 
      const typename BFSMask<TCMP>::T_SINT cmpmask = BFSMASK_NEZ(A); 
#if DOESNT_COMPILE_WITH_GCC 
      return(T_MaskGen::CreateMaskFromHighBitSized<sizeof(TCMP)>(cmpmask)); 
#else 
      return(CreateMaskFromHighBitSized<sizeof(TCMP)>(cmpmask)); 
#endif 
     } 
    }; 

    template<typename TVAL> TVAL BFWrappedInc(TVAL x,TVAL minval,TVAL maxval) 
    { 
     const TVAL diff = maxval-x; 
     const TVAL mask = BFSMask<TVAL>::Create_NEZ(diff); 
     const TVAL incx = x + 1; 
     return(BFSelect_MASK(mask,incx,minval)); 
    } 

    SINT32 currentsnap = 0; 
    SINT32 SetSnapshot() 
    { 
     currentsnap=BFWrappedInc<SINT32>(currentsnap,0,20); 
     return(currentsnap); 
    } 
} 

回答

4

由於CreateMaskFromHighBitSized不上它不是一個從屬名稱和編譯器能夠找到它的類的模板參數依賴不看模板基類。因此,如果函數應該在基類中找到,則必須指定T_MaskGen::

當名稱被明確限定爲T_MaskGen::CreateMaskFromHighBitSized時,編譯器並不清楚它總是一個模板。該template關鍵字是必要說清楚(以同樣的方式typename往往是在這些情況下使用):

return(T_MaskGen::template CreateMaskFromHighBitSized<sizeof(TCMP)>(cmpmask)); 

呼叫的這個版本應該爲FUNCTION_IN_PARENT兩個定義工作。

0

擴大對某事物給出的答案:這是C++ Templates: The Complete Guide這樣解釋,在部分9.3.3模板依賴名稱:

一般情況下,C++編譯器,需要治療<跟隨模板的名稱作爲模板參數列表的開始;否則它是一個「小於」的操作符。與類型名稱一樣,編譯器必須假設從屬名稱不指向模板,除非編程人員使用關鍵字提供額外信息[。]