Синтаксическая ошибка при специализации шаблона GCC, но не MSVC

#c #templates #visual-c #gcc #syntax

#c #шаблоны #visual-c #gcc #синтаксис

Вопрос:

Следующий код отлично компилируется с использованием MSVC 2008. При сборке GCC вылазит много ошибок (ошибка после кода). Что следует сделать, чтобы устранить ошибку?

 #define FORCE_INLINE inline
#define CREF(A) const Aamp;

template <class F>
class RDOFunCalcStd: public RDOFunCalc
{
    ...

    template <int paramCount>
    FORCE_INLINE void calc(CREF(LPRDORuntime) pRuntime);

    template <>
    FORCE_INLINE void calc<1>(CREF(LPRDORuntime) pRuntime)
    {
        m_value = m_pFunction(getParam<F::arg1_type>(pRuntime, 0));
    }

    template <>
    FORCE_INLINE void calc<2>(CREF(LPRDORuntime) pRuntime)
    {
        m_value = m_pFunction(getParam<F::arg1_type>(pRuntime, 0), getParam<F::arg2_type>(pRuntime, 1));
    }
};
  

GCC выдает следующие ошибки:

 error: too many template-parameter-lists

error: explicit specialization in non-namespace scope ‘class rdoRuntime::RDOFunCalcStd<F>’

error: variable or field ‘calc’ declared void

error: expected ‘;’ before ‘<’ token

error: expected ‘;’ before ‘template’

error: explicit specialization in non-namespace scope ‘class rdoRuntime::RDOFunCalcStd<F>’

error: variable or field ‘calc’ declared void

error: expected ‘;’ before ‘<’ token
  

Ответ №1:

MSVC позволяет, в качестве расширения, специализировать функции-члены прямо внутри класса, однако это не стандартно.

Если вы хотите специализировать функции-члены, вы должны сделать это на уровне пространства имен.

 // note: use "inline" so that the linker merges multiple definitions
template <class F>
template <>
inline void RDOFunCalcStd<F>::calc<1>(LPRDORuntime constamp; pRuntime)
{
    m_value = m_pFunction(getParam<typename F::arg1_type>(pRuntime, 0));
}
  

Кроме того, FORCE_INLINE это немного ошибочно, inline это подсказка, а не приказ компилятору, поэтому вы ничего не заставляете. И я тоже не совсем понимаю смысл CREF . Вы ни для чего не помогаете себе, используя макросы, совсем наоборот.

Ответ №2:

Обычно GCC выдает номера строк. И, возможно, вы используете некоторые функции языка C , которые лучше поддерживаются в самом последнем GCC. Вы пробовали GCC 4.6? И GCC могут быть предоставлены аргументы (как здесь или более вероятно -std=c 0x ), определяющие диалект, который он принимает. Я считаю, что недавний GCC (т. Е. g 4.6) приложил много усилий для соответствия стандарту языка. И GCC 4.6 может даже указывать номера столбцов в сообщениях об ошибках.

Комментарии:

1. На самом деле, ошибка заключается в том, что MSVC принимает здесь код. MSVC намного мягче, чем другие компиляторы. В этом конкретном случае функции-члены должны быть специализированы в области пространства имен, а не в области класса.