Проблема с вызовом GCC статических шаблонов функций в шаблонном родительском классе - PullRequest
0 голосов
/ 15 апреля 2010

У меня есть код, который компилируется и выполняется на MSVC ++, но не компилируется на GCC. Я сделал следующий тестовый фрагмент. Моей целью было переместить статический метод из BFSMask в BFSMaskSized. Может кто-нибудь объяснить, что происходит с ошибками (особенно странная ошибка 'operator <')? Спасибо. </p>

В случае, если оба #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);
    }
}

Ответы [ 2 ]

4 голосов
/ 15 апреля 2010

Поскольку CreateMaskFromHighBitSized не зависит от параметра шаблона класса, это не зависимое имя, и компилятор ожидает его найти, не глядя на шаблонный базовый класс. Следовательно, T_MaskGen:: должно быть указано, если функция должна быть найдена в базовом классе.

Когда имя явно определено как T_MaskGen::CreateMaskFromHighBitSized, для компилятора не очевидно, что это всегда будет шаблон. Ключевое слово template необходимо для ясности (таким же образом typename часто используется в этих ситуациях):

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

Эта версия вызова должна работать для обоих определений FUNCTION_IN_PARENT.

0 голосов
/ 18 января 2012

Расширяя ответ, данный sth: это объясняется в Шаблоны C ++: Полное руководство , например, в разделе 9.3.3 Зависимые имена шаблонов :

Как правило, компилятор C ++ должен обрабатывать <после имени шаблона как начало списка аргументов шаблона; в противном случае это оператор «меньше чем». Как и в случае с именами типов, компилятор должен предположить, что зависимое имя не ссылается на шаблон, если только программист не предоставит дополнительную информацию, используя ключевое слово <code>template [.]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...