1

So I have a little class where I would like to add structured binding support. However I cannot figure out how to specialize std::tuple_element and std::tuple_size with my templated class. This is my attempt:

template<typename... Cmps>
struct CmpGroup
{
    std::array<void*, sizeof...(Cmps)> cmps;

    template<typename C>
    C& get()
    {
        constexpr int index = GetIndexInPack<C, Cmps...>::value;
        static_assert(index != -1);
        return *static_cast<C*>(index);
    }

    template<size_t I>
    auto& get()
    {
        static_assert(I < sizeof...(Cmps));
        using CmpType = typename GetTypeInPack<I, Cmps...>::type;
        return *static_cast<CmpType*>(cmps[I]);
    }
};

namespace std
{
    template<typename... Types>
    struct tuple_size<CmpGroup<Types...>> : public integral_constant<size_t, sizeof...(Types)>;

    template<std::size_t N, typename... Types>
    struct tuple_element<N, CmpGroup<Types...>> {
        //got this from: https://blog.tartanllama.xyz/structured-bindings/
        using type = decltype(std::declval<CmpGroup<Types...>>().template get<N>());
    };
}

(I have left out some implementation specific things for clarity, the full snippet can be found here )

However this causes the tuple_size specialization to give a compile error: error C2143: syntax error: missing ',' before ';'

Is it even possible to allow a templated class to have structured bindings or am I missing something?

1 Answers1

3

As it turns out, my tuple_size specialization needed to have a body which I overlooked.

template<typename... Types>
struct tuple_size<CmpGroup<Types...>> : public integral_constant<size_t, sizeof...(Types)>{};
------------------------------------------------------------------------------------------^^

Thanks @BoPersson for pointing that out!