是否有其他可能?
关于正确性,JVApen回答(+1)。
一种可能的选择是避免
std::array
并使用模板专门化以递归方式构造索引序列
下面是一个完整的可编译示例
#include <utility>
#include <type_traits>
template <typename, std::size_t, bool...>
struct bar;
// true case
template <std::size_t ... Is, std::size_t I, bool ... Bs>
struct bar<std::index_sequence<Is...>, I, true, Bs...>
: public bar<std::index_sequence<Is..., I>, I+1U, Bs...>
{ };
// false case
template <std::size_t ... Is, std::size_t I, bool ... Bs>
struct bar<std::index_sequence<Is...>, I, false, Bs...>
: public bar<std::index_sequence<Is...>, I+1U, Bs...>
{ };
// end case
template <typename T, std::size_t I>
struct bar<T, I>
{ using type = T; };
template <bool ... Bs>
struct foo : public bar<std::index_sequence<>, 0U, Bs...>
{ };
int main()
{
static_assert( std::is_same<typename foo<false, true, true>::type,
std::index_sequence<1U, 2U>>{}, "!" );
}
如果您不喜欢递归解决方案,我建议(只是为了好玩)另一个基于
std::tuple_cat
#include <tuple>
#include <utility>
#include <type_traits>
template <std::size_t, bool>
struct baz
{ using type = std::tuple<>; };
template <std::size_t I>
struct baz<I, true>
{ using type = std::tuple<std::integral_constant<std::size_t, I>>; };
template <std::size_t I, bool B>
using baz_t = typename baz<I, B>::type;
template <typename, bool...>
struct bar;
template <std::size_t ... Is, bool ... Bs>
struct bar<std::index_sequence<Is...>, Bs...>
{
template <std::size_t ... Js>
constexpr static std::index_sequence<Js...>
func (std::tuple<std::integral_constant<std::size_t, Js>...> const &);
using type = decltype(func(std::tuple_cat(baz_t<Is, Bs>{}...)));
};
template <bool ... Bs>
struct foo : public bar<std::make_index_sequence<sizeof...(Bs)>, Bs...>
{ };
int main()
{
static_assert( std::is_same<typename foo<false, true, true>::type,
std::index_sequence<1U, 2U>>{}, "!" );
}