简体   繁体   中英

Invoking a member function with variadic template parameters that are not part of the function's arguments

Most of the questions I have found revolve around non-member functions where the variadic template parameters are also found in the function's arguments.

In my case, I am in a situation where I would like to filter the types coming into one of the variadic member functions and pass the filtered types to another variadic member function:

#include <tuple>
#include <type_traits>

template<typename...Ts>
using tuple_cat_t = decltype(std::tuple_cat(std::declval<Ts>()...));

// how the filtering of the types happen is not relevant
template<typename T, typename...Ts>
using remove_t = tuple_cat_t<
    typename std::is_empty_v<T>,
        std::tuple<>,
        std::tuple<Ts>
    >::type...
>;

struct Foo
{
    template <typename... T_Tags>
    void Bar(float arg)
    {
        // I would like to call DoBar() with a filtered set of T_Tags
        // where type filtering is done with something similar to what is outlined
        // here: https://stackoverflow.com/a/23863962/368599
        using filtered_args = std::remove_t<T_Tags...>;

        // not sure of the syntax here or if this is even possible
        std::invoke(&Foo::DoBar<???filtered_args???>, std::tuple_cat(std::make_tuple(this), std::make_tuple(arg)));
    }

    template <typename... T_FilteredTags>
    void DoBar(float arg)
    {
        // Do something with T_FilteredTags types
    }
};

You can use template lambda to expand the filtered types and specify them to DoBar explicitly

struct Foo
{
    template <typename First_Tag, typename... T_Tags>
    void Bar(float arg)
    {
        using filtered_args = remove_t<First_Tag, T_Tags...>;

        [&]<typename... T_FilteredTags>(std::tuple<T_FilteredTags...>*) { 
          std::invoke(&Foo::DoBar<T_FilteredTags...>, this, arg);
        } (static_cast<filtered_args*>(nullptr));
    }

    template<typename... T_FilteredTags>
    void DoBar(float arg)
    {
      // Do something with T_FilteredTags types
    }
};

Noted that there is no need to use tuple to concatenate this and arg , just pass them to std::invoke directly.

Demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM