почему не компилируется
template <class T = int>
typename boost::enable_if<boost::is_integral<T> >::type
class Ewma {
};
Здравствуйте, gpepsi, Вы писали:
G>почему не компилируется
некорректный синтаксис потому что %)
G>G> template <class T = int>
G> typename boost::enable_if<boost::is_integral<T> >::type
G> class Ewma {
G> };
G>
выделенная строчка тупо лишняя в объявлении класса...
нужно пользовать специализации для классов
Здравствуйте, gpepsi, Вы писали:
G>почему не компилируется
G>G> template <class T = int>
G> typename boost::enable_if<boost::is_integral<T> >::type
G> class Ewma {
G> };
G>
А должно?
Это в случае целочисленного Т эквивалентно
template <class T = int>
void
class Ewma {
};
с чего бы этому компилироваться
Если тебе просто нужно ограничить тип Т до целочисленных (т.е. чтоб все остальное не компилировалось), используй ассерты:
template <class T = int>
class Ewma {
BOOST_MPL_ASSERT(( boost::is_integral<T> ));
};
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, gpepsi, Вы писали:
G>>почему не компилируется
G>>G>> template <class T = int>
G>> typename boost::enable_if<boost::is_integral<T> >::type
G>> class Ewma {
G>> };
G>>
J>А должно?
J>Это в случае целочисленного Т эквивалентно
J>J> template <class T = int>
J> void
J> class Ewma {
J> };
J>
J>с чего бы этому компилироваться
J>Если тебе просто нужно ограничить тип Т до целочисленных (т.е. чтоб все остальное не компилировалось), используй ассерты:
странно..., думал, что можно без assert-ов
J>J> template <class T = int>
J> class Ewma {
J> BOOST_MPL_ASSERT(( boost::is_integral<T> ));
J> };
J>
Здравствуйте, gpepsi, Вы писали:
G>почему не компилируется
концептов нет.
G> template <class T = int>
G> typename boost::enable_if<boost::is_integral<T> >::type
G> class Ewma {
G> };
template <class T = int, bool is_integral = boost::is_integral<T>::value > class Ewma;
template <class T >
class Ewma< T,true> {
};
Здравствуйте, gpepsi, Вы писали:
G>странно..., думал, что можно без assert-ов
Ты просто должен понимать, как работает enable_if и в каких ситуациях нужно то, как он работает.
enable_if< condition, your_type > — это тип (класс), который устроен следующим образом: если condition выполняется, то внутри этого типа будет typedef your_type type; (your_type — это void по умолчанию), а если не выполняется, то это просто будет пустая структура.
На псевдокоде это будет так:
tepmlate< class condition, class your_type = void >
struct enable_if
{
#if (condition::value == true)
typedef your_type type;
#endif
};
(здесь #if аналогичен static_if из D — препроцессор, который может взаимодействовать с языком).
Таким образом, когда ты пишешь enable_if< condition, your_type >::type, это даст тебе your_type, если condition выполняется, и ошибку в противном случае, так как никакого type внутри нету.
Поэтому если enable_if<>::type используется в сигнатуре функции, то при невыполнении condition происходит так называемая ошибка подстановки (substitution failure), но, по правилу SFINAE (substitution failure is not an error), если при разрешении перегрузки мы напарываемся на ошибку подстановки, то мы не трактуем ее как ошибку компиляции, а просто выбрасываем соответствующую функцию из множества функций, рассматриваемых в контексте данного вызова.
Поэтому применение enable_if (т.е. эксплуатация наличия/отсутствия type внутри в зависимости от какого-то условия) осмысленно только при работе с функциями, так как там сработает SFINAE, и может быть еще в каких-то экзотических случаях, которые я не могу сходу придумать, а в остальных случаях удобнее работать напрямую с условием.