sky*_*ack 6 c++ templates variadic-templates std-function c++14
鉴于可调用函数的类型C,我想在编译时得到一个std::function; 其类型:
CN函数的第一个参数类型C这意味着,对于给定类型void(int, char, double)和给定N,函数的类型是:
N = 1 =>结果类型: std::function<void(int)>N = 2 =>结果类型: std::function<void(int, char)>N = 3 =>结果类型: std::function<void(int, char, double)>N > 3 =>编译时错误例:
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...>());
};
Run Code Online (Sandbox Code Playgroud)
它遵循可能的解决方案:
#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,
"!"
);
}
Run Code Online (Sandbox Code Playgroud)
基本思想是使用a tuple和那些属于标准模板库的实用程序(作为示例std::tuple_element),将它们与放置在正确位置的包扩展混合在一起.
为此,我使用了一个constexpr返回std::function给定类型的空对象的函数.然后,函数的类型通过a获取,decltype并FuncType使用别名作为对象的类型导出.
一切都在编译时进行.
为了推导出该函数的正确类型,我使用了一个众所周知的模式,它std::integer_sequence通过扩展索引来实现并实际解包元组的类型.
| 归档时间: |
|
| 查看次数: |
231 次 |
| 最近记录: |