创建一个带有有限参数的std :: function类型 [英] Create a std::function type with limited arguments
问题描述
给定可调用函数 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 functionC
这意味着对于给定类型 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 = 3
=>结果类型:std :: function< void(int,char,double) >
-
N> 3
=>编译时错误
N = 2
=>结果类型: std :: function< void(int,char)>
/ li> 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屋!