2

I can imagine a straightforward efficient implementation of fold expression expansion when all types of parameter pack are the same (simplified c++11 example):

#include <type_traits>
#include <array>

template <bool...>
struct bool_pack { };

template <bool... Bs>
using and_ = std::is_same<bool_pack<true, Bs...>, bool_pack<Bs..., true>>;

template <std::size_t I, std::size_t N, class T>
constexpr typename std::enable_if<(I == N - 1),T>::type fold_impl_impl(std::array<T, N> const &arr) {
    return arr[I];
}

template <std::size_t I, std::size_t N, class T>
constexpr typename std::enable_if<(I < N - 1),T>::type fold_impl_impl(std::array<T, N> const &arr) {
    return arr[I] + fold_impl_impl<I+1, N>(arr);
}

template <class T, std::size_t N>
constexpr T fold_impl(std::array<T, N> arr) {
    return fold_impl_impl<0, N>(arr);
}

template <class T, class... Ts>
constexpr typename std::enable_if<and_<std::is_same<T, Ts>::value...>::value, T>::type fold(T first, Ts... rest) {
    return fold_impl<T, sizeof...(Ts) + 1>({{first, rest...}});
}

int main() {
    static_assert(fold(1, 2, 3, 4) == 10, "!");
}

Of course when we consider more general case, that is, when we can't really assume that the types are the same, we could replace reference to the std::array with reference to the std::tuple of parameter types. In this case however the tuple itself would most probably cause the complexity of the expansion to grow with a logarithm of parameter number.

IT would be possible to make the fold expressions to be treated intrinsically by the compiler to be sure the complexity of expansion is O(N), but in c++ standard draft in section [expr.prim.fold] I can't see guarantees on this.

Can we assume expansion of parameter pack using fold expression is cheap?

W.F.
  • 13,888
  • 2
  • 34
  • 81

0 Answers0