Home > Back-end >  Is there easier way to check for a variadic template type?
Is there easier way to check for a variadic template type?

Time:09-19

I've got a function

template<typename T, typename FuncT, typename ... Args>
static void Submit(Handle<T> handle, FuncT&& funcT, Args&& ... args);

Handle is a class that contains an index to the data inside some array. This data can be retrieved through a handle_cast function.

T& data = *handle_cast<T*>(handle);

I'm not going to cover this implementation, because it's not related to my question.

Handle<T> handle is the main handle to a resource. I'd like args to be a mix, sometimes it'd be a handle, sometimes a different data.

FuncT first argument is T& and the rest of the arguments might be either *handle_cast<Args*> if this argument is Handle<Some Type> or just Arg

I came out with this solution, but I'm not sure if it's correct or maybe it could be done easier.

template<typename T, typename FuncT, typename ... Args>
    static void Submit(Handle<T> handle, FuncT&& funcT, Args&& ... args) 
{
    std::variant<Args...> v;
    bool isHandle = std::visit([](auto&& arg) {
        using T = std::decay_t<decltype(arg)>;
        if constexpr (std::is_base_of_v<HandleBase, T>) {
            return true;
        } return false;
    }, v);

    func(*handle_cast<T*>(handle), std::forward<Args>(isHandle ? *handle_cast<Args*>(args) : args)...);
}

Is this solution ok or it can be done easier/cleaner?

CodePudding user response:

You may be looking for something like this (not tested):

// Cloned from the standard std::forward
template<typename T>
T&& maybe_handle_forward(typename std::remove_reference<T>::type& t ) noexcept {
  return std::forward<T>(t);
}

template<typename T>
T& maybe_handle_forward(Handle<T> h) noexcept {
  return *handle_cast<T*>(h);
}

Now you can write

func(*handle_cast<T*>(handle), maybe_handle_forward<Args>(args)...);
  •  Tags:  
  • c
  • Related