1
\$\begingroup\$

I was able to get some very helpful code to get tuple values on a previous question. I was able to reduce my duplication a lot. But I'm having trouble wrapping this code in its own helper class so it can be reused in other classes. How can I improve this code to allow this?

This is the tuple code:

// Inserted invoke to use `void` as filling for holes
template<class T, class F>
constexpr auto invoke(F &&f, std::size_t I) -> std::enable_if_t<!std::is_same<T, void>::value> {
    f((T *) 0, I);
}

template<class T, class F>
constexpr auto invoke(F &&, std::size_t) -> std::enable_if_t<std::is_same<T, void>::value> {
}

template<class tuple, class F, std::size_t... I>
constexpr void forAllTypesImpl(F &&f, std::index_sequence<I...>) {
    int x[] = {0, (invoke<std::tuple_element_t<I, tuple>>(f, I), 0)...};
    static_cast<void>(x);
}

template<class tuple, class F>
void forAllTypes(F &&f) {
    forAllTypesImpl<tuple>(f, std::make_index_sequence<std::tuple_size<tuple>::value>());
}

template<class R, class tuple, class F>
R getOne(F &&f, std::size_t i) {
    R r;
    forAllTypes<tuple>([&](auto p, std::size_t j) {
        if (i == j) {
            r = f(p);
        }
    });
    return r;
}

I have a method that uses this code to create an event class instance by passing an event type enum:

using eventClasses = std::tuple<Event::SetMatchType, Event::SetTeam, Event::SetPlayer, Event::StartMatch, void, void, Event::StartInnings, Event::StartOver, Event::Ball, Event::ExtraBall, Event::Wicket, Event::Penalty, Event::Retire, Event::EndOver, Event::EndInnings, void, Event::EndMatch, Event::SwapBatsman, void, Event::NewBatsman, Event::NewBowler, Event::NewWicketKeeper, Event::SetCaptain, void, void, Event::Undo>;

template<class... X, class ET>
std::shared_ptr<Event> Event::createInstance(const ET eventType, X&&... x) {
    return getOne<std::shared_ptr<Event>, eventClasses>([&](auto p) {
        return std::make_shared<std::decay_t<decltype(*p)>>(std::forward<X>(x)...);
    }, static_cast<std::size_t>(eventType));
}

To create an event class, I give it an enum and the parameters it needs for the constructor (in this case json):

auto event = createInstance(eventType, serializedJson);

The code above works just fine until I try to put the tuple code into its own helper class and I get an intended error.

\$\endgroup\$
  • \$\begingroup\$ @Jamal, the code that is posted here is working. \$\endgroup\$ – Daniel Ryan Jul 3 '17 at 3:31
  • \$\begingroup\$ What about the error? \$\endgroup\$ – Jamal Jul 3 '17 at 3:51
  • \$\begingroup\$ I've asked for code improvements so this can be used in its own class (it works just fine otherwise). The error is to explain what happens when I try to do this. I've edited the above to make this clearer. \$\endgroup\$ – Daniel Ryan Jul 3 '17 at 4:02
0
\$\begingroup\$

Looks like if I have all the code in its own header file (no class file) it works just fine.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.