0

For an embedded solution I want to define an array of void(*relay)(void) functions which I use as callback relays for a library which only accepts stateless void(*f)(void) callbacks. The relays will then call the actual std::function callbacks.

The code below works nicely. However, I'm looking for a possibility to change the number of relay functions without having to manually type their initialization to the array. A compile time solution would be nice but initialization of the array at runtime would be fine as well.

Any chance to implement such a thing in C++?

constexpr size_t nrOfRelays = 5;

std::function<void(void)> cb[nrOfRelays]; // callbacks

void (*const relays[nrOfRelays])(void)    // array of pointers to void(*relay)(void)
{
    [] { cb[0](); },
    [] { cb[1](); },
    [] { cb[2](); },
    [] { cb[3](); },
    [] { cb[4](); },
};

void test(unsigned nr, std::function<void(void)> callback)
{
    cb[nr] = callback;
    attachCallback(nr, relays[nr]); // lib requires a void(*f)() callback
}
0

1 Answer 1

1

I don't think it's possible with a plain array. You'll need to use something like std::array to be able to return it from a helper function/lambda.

Here's a C++20 solution with a lambda template:

constexpr std::array<void(*)(), nrOfRelays> relays =
    []<std::size_t ...I>(std::index_sequence<I...>) {
        return std::array<void(*)(), nrOfRelays>{[]{cb[I]();}...};
    }(std::make_index_sequence<nrOfRelays>{});

And here's a C++17 one with a helper function:

template <std::size_t ...I>
constexpr std::array<void(*)(), nrOfRelays> MakeRelays(std::index_sequence<I...>)
{
    return std::array<void(*)(), nrOfRelays>{[]{cb[I]();}...};
}

constexpr auto relays = MakeRelays(std::make_index_sequence<nrOfRelays>{});

The second solution can be used in C++14 if you replace the lambda with a template function:

template <std::size_t I> void helper() {cb[I]();}

template <std::size_t ...I>
constexpr std::array<void(*)(), nrOfRelays> MakeRelays(std::index_sequence<I...>)
{
    return std::array<void(*)(), nrOfRelays>{helper<I>...};
}

constexpr auto relays = MakeRelays(std::make_index_sequence<nrOfRelays>{});
Sign up to request clarification or add additional context in comments.

1 Comment

I tried the C++17 version which works perfectly. But I can't figure out how to implement the proposed change for the C++14 version. Mind to show the changed code?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.