【问题标题】:Transforming std::tuple<T...> to T将 std::tuple<T...> 转换为 T
【发布时间】:2013-03-07 11:30:43
【问题描述】:

所以我得到了一个std::tuple&lt;T...&gt;,我想创建一个接受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&lt;V&gt;::value 的每个索引,我似乎无法找到一种方法。 FunctionPtr 是在上下文中定义的,其中V=std::tuple&lt;T...&gt;(也已经有一个可变参数模板(因此我不能直接传递T...))

我想我需要生成一些索引列表,然后做一些黑魔法..

【问题讨论】:

标签: c++ templates c++11 stdtuple


【解决方案1】:

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

#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;
}

【讨论】:

  • 太棒了! - 我已经破解了很长一段时间了,你只是眨眼间就把它修好了! - 看来我仍然需要大量练习元组和可变参数模板;)
  • @Skeen:这很正常,需要一段时间才能掌握它
  • @AndyProwl:你知道是否允许保留FunctionPtr的原始定义并为元组添加一个specialization
  • @MatthieuM.:您的意思是部分专门化别名模板?不,这是禁止的……
  • @MatthieuM.:标准参考是 14.5/3:“因为别名声明不能声明模板 ID,所以不能部分或显式特化别名模板。"
【解决方案2】:

一个简单的特征就可以解决问题:

#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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-31
    • 2019-10-20
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多