#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 намного мягче, чем другие компиляторы. В этом конкретном случае функции-члены должны быть специализированы в области пространства имен, а не в области класса.