创建一个带有有限参数的std :: function类型 [英] Create a std::function type with limited arguments

查看:146
本文介绍了创建一个带有有限参数的std :: function类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定可调用函数 C 的类型,我想在编译时获得 std :: function ;其类型:

Given the type of a callable function C, I want to get at compile time a std::function; the type of which:


  • 具有相同的函数返回类型 C li>
  • 参数类型是函数 C
  • 的第一个 N >
  • has the same return type of function C
  • the argument types are the first N argument types of function C

这意味着对于给定类型 void(int,char,double)给定 N ,函数的类型为:

This means that, for a given type void(int, char, double) and a given N, the type of the function is:


  • N = 1 =>结果类型: std :: function< void(int)>
  • li> N = 2 =>结果类型: std :: function< void(int,char)> / li>
  • N = 3 =>结果类型: std :: function< void(int,char,double) >

  • N> 3 =>编译时错误

  • N = 1 => result type: std::function<void(int)>
  • N = 2 => result type: std::function<void(int, char)>
  • N = 3 => result type: std::function<void(int, char, double)>
  • N > 3 => compile time error

示例:

template<std::size_t N, typename R, typename... A>
constexpr auto get() {
    return /*(magically somehow)*/ std::function<R(FirstNFromA...)>
}

template<std::size_t N, typename R, typename... A>
struct S {
    using func = decltype(get<N, R, A...>());
};


推荐答案

它遵循一种可能的解决方案:

It follows a possible solution:

#include <tuple>
#include <utility>
#include <functional>
#include <type_traits>

template<
    typename R,
    typename... A,
    std::size_t... I,
    std::enable_if_t<(sizeof...(I)<=sizeof...(A))>* = nullptr
> constexpr auto
get(std::integer_sequence<std::size_t, I...>) {
    return std::function<R(std::tuple_element_t<I, std::tuple<A...>>...)>{};
}

template<std::size_t, typename>
struct FuncType;

template<std::size_t N, typename R, typename... A>
struct FuncType<N, R(A...)> {
    using Type = decltype(get<R, A...>(std::make_index_sequence<N>{}));
};

int main() {
    static_assert(
        std::is_same<
            FuncType<2, void(int, char, double, int)>::Type,
            std::function<void(int, char)>
        >::value,
        "!"
    );
}

基本思想是使用 tuple 和那些作为标准模板库一部分的实用程序(例如, std :: tuple_element ),将它们与右侧的包扩展

为此,我使用了一个返回空的 constexpr 函数 std :: function code>给定类型的对象。然后,通过 decltype 获取函数的类型,并将其作为 FuncType 对象的类型导出别名。

一切都在编译时发生。

为了推导出该函数的正确类型,我使用了一个众所周知的模式,它涉及一个 std :: integer_sequence ,并通过展开索引实际解压缩一个元组的类型。

The basic idea is to use a tuple and those utilities that are part of the Standard template Library (as an example, std::tuple_element), mix them with a pack expansion placed in the right place and that's all.
To do that, I used a constexpr function that returns an empty std::function object of the given type. Then the type of the function is taken by means of a decltype and exported as a type of the FuncType object using an alias.
Everything takes place at compile time.
In order to deduce the right type for that function, I used a well known pattern that involves a std::integer_sequence and actually unpack the types of a tuple by expanding the indexes.

这篇关于创建一个带有有限参数的std :: function类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆