代码之家  ›  专栏  ›  技术社区  ›  Adisak

GCC在模板化父类中调用静态模板函数时出现问题

  •  0
  • Adisak  · 技术社区  · 16 年前

    我有一些在MSVC++上编译和运行的代码,但不会在GCC上编译。我做了一个测试片段如下。我的目标是将静态方法从BFSMask移到BFSMaskSized。有人能解释一下这些错误是怎么回事吗(特别是奇怪的“运算符”<'错误)?非常感谢。

    #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);
        }
    }
    
    2 回复  |  直到 16 年前
        1
  •  4
  •   sth    16 年前

    CreateMaskFromHighBitSized 不依赖于类的模板参数它不是依赖名称,编译器希望在不查看模板化基类的情况下找到它。因此 T_MaskGen:: 必须指定是否应在基类中找到函数。

    当名称显式限定为 T_MaskGen::CreateMaskFromHighBitSized template 关键字是必要的,以明确这一点(以同样的方式) typename 通常用于以下情况:

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

    此版本的调用应适用于 FUNCTION_IN_PARENT .

        2
  •  0
  •   Emil Styrke    14 年前

    扩展某物给出的答案:这在 C++ Templates: The Complete Guide 像这样,一节一节 9.3.3模板的从属名称 :

    template [.]