Шаблонные функции не могут быть частично специализированными. Есть несколько вещей, которые вы можете сделать: вы можете обернуть функцию в шаблон класса с помощью одного статического метода и специализировать шаблон класса, или вы можете использовать SFINAE, чтобы выбрать лучший выбор функции среди различных функций шаблона:
template <typename O, typename Args...>
void single_op_wrapper( /* all but failval */ ) { // [+]
// implementation for void
}
template <typename R, typename O, typename Args...>
typename boost::enable_if< boost::is_same<R,bool>, bool >::type // bool if condition is met
single_op_wrapper( /* all args */ ) {
// implementation for R being a bool
}
template <typename R, typename O, typename Args...>
typename boost::enable_if< boost::is_same<R,char> >::type // by default bool
single_op_wrapper( /* all args */ ) {
// implementation for void return
}
template <typename R, typename O, typename Args...>
typename boost::disable_if_c< boost::is_same<R,char>::value //[*]
|| boost::is_same<R,bool>::value
, R >::type
single_op_wrapper( /* all args */ ) {
// implementation when R is neither bool nor void
}
На отдельном шаблоне для void [+]:
В C ++ вы не можете иметь функцию, которая принимает аргумент типа void
. Это означает, что вы не можете использовать те же аргументы для случая void
, что и для остальных.
На стороне метапрограммирования:
Здесь есть пара хитрых битов ... enable_if
- это метафункция, которая определяет внутренний тип, если выполняется условие или ничего иного. Когда компилятор пытается заменить типы в шаблоне, возвращаемый тип будет действительным (и, как таковая, функция будет кандидатом), только если условие выполнено. Метафункция disable_if
имеет противоположное поведение. Прямой вариант enable_if
/ disable_if
принимает метафункцию в качестве первого аргумента и, необязательно, тип в качестве второго аргумента. Вторая версия enable_if_c
/ disable_if_c
принимает логическое значение в качестве первого аргумента.
В [*] важно отметить, что функции должны быть эксклюзивными. То есть, если для данного типа более одного из шаблонов являются кандидатами, так как ни один из них не является специализацией других, компилятор остановится с ошибкой неоднозначности. Вот причина использования disable_if
в последнем шаблоне.
Примечание: я использовал boost
пространство имен вместо std
, так как я никогда не играл с метапрограммированием в c ++ 0x, но я считаю, что вы можете изменить boost
пространство имен с std
в вашем компиляторе , Проверьте документы заранее!