I have a struct sequence
similar to std::integer_sequence
, but it can hold values of multiple types as non-type template parameters (sort of like a compile-time tuple). It is implicitly constructible from std::integer_sequence
by using a constexpr
constructor and a user-defined deduction guide. I also have a function apply_constexpr
that applies a non-type template parameter pack to a function, similarly to std::apply
. Here they are:
template <auto...>
struct sequence {
template <typename T, T... Ts>
constexpr sequence(std::integer_sequence<T, Ts...>) noexcept {
}
};
template <typename T, T... Ts>
sequence(std::integer_sequence<T, Ts...>) -> sequence<Ts...>;
template<typename Fn, auto... Vals>
constexpr std::invoke_result_t<Fn, decltype(Vals)...>
apply_constexpr(Fn&& fn, sequence<Vals...>)
noexcept(std::is_nothrow_invocable_v<Fn, decltype(Vals)...>) {
return fn(std::forward<decltype(Vals)>(Vals)...);
}
They can be used like this:
static_assert(apply_constexpr(
[&](auto&&... i) { return ((f(i) == g(i)) && ...); },
sequence{ std::make_index_sequence<100>() })
);
When the sequence
is constructed explicitly like above, everything is fine. However because the constructor is not explicit
the following also works:
sequence s = std::make_index_sequence<100>();
But despite it working, the following does not work (candidate template ignored: could not match 'sequence' against 'integer_sequence'
):
static_assert(apply_constexpr(
[&](auto&&... i) { return ((f(i) == g(i)) && ...); },
std::make_index_sequence<100>())
// no "sequence{ ... }" here, trying to rely on implicit conversion
);
Why doesn't it work and what could I do to make it work?
You could make an overload that forward to your first
apply_constexpr
function. Something like this.The reason it doesn't work in the first place is that template deduction is always on the exact type. When deducing the compiler will not consider conversions. If you pass a
std::integer_sequence
, that's what the compiler will deduce.Doing conversions and deductions in one step is not supported by the language.