Given the well-known indices infrastructure:
namespace detail
{
template<int... Is>
struct seq { };
template<int N, int... Is>
struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };
template<int... Is>
struct gen_seq<0, Is...> : seq<Is...> { };
}
You could redefine your class template this way:
template<int N, typename T>
struct Container {
template<typename... Ts>
Container(Ts&&... vs) : data{{std::forward<Ts>(vs)...}} {
static_assert(sizeof...(Ts)==N,"Not enough args supplied!");
}
template<typename F>
void doOperation(F&& func)
{
doOperation(std::forward<F>(func), detail::gen_seq<N>());
}
template<typename F, int... Is>
void doOperation(F&& func, detail::seq<Is...>)
{
(std::forward<F>(func))(data[Is]...);
}
std::array<T,N> data;
};
Here is a live example.
Notice, that you do not need to construct an std::function
object in main()
: the std::function
can be implicitly constructed from the lambda. However, you do not even need to use std::function
at all here, possibly incurring in an unnecessary run-time overhead.
In the solution above, I just let the type of the callable object to be a template parameter that can be deduced by the compiler.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…