Transforming std::tuple<T...> to T

Transforming std::tuple<T...> to T

本文关键字:gt to std tuple lt Transforming      更新时间:2023-10-16

所以我有一个std::tuple<T...>,我想创建一个接受T...的函数指针,目前这是我得到的;

template<typename... Arguments>
using FunctionPointer = void (*)(Arguments...);
using FunctionPtr = FunctionPointer<typename std::tuple_element<0, V>::type,
                                    typename std::tuple_element<1, V>::type,
                                    typename std::tuple_element<2, V>::type>;

然而,我似乎找不到一种方法来做到这一点,而无需手动输入0, ..., tuple_size<V>::value的每个索引。FunctionPtr是在上下文中定义的,其中V=std::tuple<T...>(也已经有一个可变模板(因此我不能直接传递T...))

我想我需要生成一些索引列表,并做一些黑魔法…

这是一个可能的解决方案:

#include <tuple>
// This is what you already have...
template<typename... Arguments>
using FunctionPointer = void (*)(Arguments...);
// Some new machinery the end user does not need to no about
namespace detail
{
    template<typename>
    struct from_tuple { };
    template<typename... Ts>
    struct from_tuple<std::tuple<Ts...>>
    {
        using FunctionPtr = FunctionPointer<Ts...>;
    };
}
//=================================================================
// This is how your original alias template ends up being rewritten
//=================================================================
template<typename T>
using FunctionPtr = typename detail::from_tuple<T>::FunctionPtr;

你可以这样使用它:

// Some function to test if the alias template works correctly
void foo(int, double, bool) { }
int main()
{
    // Given a tuple type...
    using my_tuple = std::tuple<int, double, bool>;
    // Retrieve the associated function pointer type...
    using my_fxn_ptr = FunctionPtr<my_tuple>; // <== This should be what you want
    // And verify the function pointer type is correct!
    my_fxn_ptr ptr = &foo;
}

一个简单的trait就可以做到:

#include <tuple>
template <typename> struct tuple_to_function;
template <typename ...Args>
struct tuple_to_function<std::tuple<Args...>>
{
    typedef void (*type)(Args...);
};

用法:

typedef std::tuple<Foo, Bar, int> myTuple;
tuple_to_function<myTuple>::type fp; // is a void (*)(Foo, Bar, int)