https://gcc.godbolt.org/z/EaPqKfvne
You could get around this by using a wrapper function, at the cost of a slightly different interface:
template <typename T, void (*fn)(T *)> void wrapper(void *d) { fn((T *)d); } template <typename T, void (*fn)(T *)> Func0 MkFunc0(T* d) { auto res = Func0{}; res.fn = (void *)wrapper<T, fn>; res.userData = (void*)d; return res; } ... Func0 x = MkFunc0<int, my_func>(nullptr);
https://gcc.godbolt.org/z/EaPqKfvne
You could get around this by using a wrapper function, at the cost of a slightly different interface:
(This approach also requires explicitly writing the argument type. It's possible to remove the need for this, but not without the kind of complexity you're trying to avoid.)