как SFINAE для включения функции-члена, возвращающей `auto`

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

 template<int N> struct A {
int sum() const noexcept
{ return _sum<N-1>(); }
private:
int _data[N];
template<int I> typename std::enable_if< I,int>::type _sum() const noexcept
{ return _sum<I-1>() + _data[I]; }
template<int I> typename std::enable_if<!I,int>::type _sum() const noexcept
{ return _data[I]; }
};

Тем не менее, это не будет работать, если рассматриваемая функция (_sum() в приведенном выше примере) имеет автоматически определяемый тип возврата, например _func() в этом примере

template<int N> class A
{
/* ... */
private:
// how to make SFINAE work for _func() ?
template<int I, typename BinaryOp, typename UnaryFunc>
auto _func(BinaryOp op, UnaryFunc f) const noexcept -> decltype(f(_data[0]))
{ return op(_func<I-1>(op,f),f(_data[I])); }
};

Что еще можно сделать, чтобы получить СФИНА здесь?

3

Решение

После David Rodríguez — dribeas следующий код работал так, как задумано:

template<int N> class A
{
int min_abs() const noexcept
{
return _func<N-1>([](int x, int y)->int { return std::min(x,y); },
[](int x)->int { return std::abs(x); });
}
private:
int _data[N];

template<int I, typename BinaryOp, typename UnaryFunc>
auto _func(BinaryOp op, UnaryFunc f) const noexcept
-> typename std::enable_if< I>,decltype(f(_data[0]))>::type
{ return op(_func<I-1>(op,f),f(_data[I])); }

template<int I, typename BinaryOp, typename UnaryFunc>
auto _func(BinaryOp op, UnaryFunc f) const noexcept
-> typename std::enable_if<!I>,decltype(f(_data[0]))>::type
{ return f(_data[I]); }
};

строго говоря, мы должны также убедиться, что бинарный оператор op возвращает правильный тип. Для простоты и краткости ответа оставляю читателю понять, что …

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector