多个可变模板功能
Multiple variadic templates function
本文关键字:功能 更新时间:2023-10-16
假设我有两个函数f1()
和f2()
,定义如下:
template<class ... Types> void f1(Types ... args1)
template<class ... Types> void f2(Types ... args2)
现在我想创建第三个函数f3()
,它接受输入f1()
和f2()
,我如何用args1...
和args2...
定义f3()
?
template<class F1, class F2> void f3(F1 f1, F2 f2) {
f1(); // how do I call f1? I need to pass in the args...
}
你不能。
因为模板函数是一组函数。你可以传递一个函数,解释模板类型,
f3(f1<int, long, long>, f2<char, int>);
而不是全套功能。
我能建议的最好的方法是将你的模板函数封装在structs 中
struct s1
{
template <typename ... Types>
static void f1 (Types ... args1)
{ }
};
struct s2
{
template <typename ... Types>
static void f2 (Types ... args2)
{ }
};
因此您可以将传递给f3()
s1
和s2
对象
s1 a;
s2 b;
f3(a, b);
或者只是类型
f3<s1, s2>();
正如Jarod42所建议的,您还可以将f1()
和f2()
封装在几个Lambda(仅来自C++14)中
auto l1 = [](auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = [](auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };
f3(l1, l2)
我的意思是,当我调用f3时,我提供f1和f2。我还需要传入f1和f2的参数。我该怎么做?
但是f1()
和f2()
的参数是相同的?还是两套不同的?
在第一种情况下,您可以将它们作为模板变量参数传递;(按照Jarod42的建议)
template <typename L1, typename L2, typename ... Args>
void f3 (L1 l1, L2 l2, Args const & ... as)
{
L1(as...);
L2(as...);
}
auto l1 = [](auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = [](auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };
f3(l1, l2, 1, '2', 3L, 4ULL);
如果您需要两个不同的参数集,则需要将这些参数包装在std::tuple
或类似的文件中。
template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1, std::tuple<As2...> const & t2)
{
std::apply(l1, t1);
std::apply(l2, t2);
}
auto l1 = [](auto&& ... args) { f1(std::forward<decltype(args)>(args)...); };
auto l2 = [](auto&& ... args) { f2(std::forward<decltype(args)>(args)...); };
f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));
但考虑到std::apply()
只能从C++17中获得:之前从元组中提取参数有点复杂。
如果没有c++17,我该如何做到这一点?
下面是一个完整的C++14示例,它使用std::index_sequence_for
和std::index_sequence
对元组进行解包
#include <tuple>
#include <iostream>
#include <type_traits>
template <typename ... Ts>
void f1 (Ts ... as)
{ std::cout << "- f1: " << sizeof...(Ts) << " arguments" << std::endl; }
template <typename ... Ts>
void f2 (Ts ... as)
{ std::cout << "- f2: " << sizeof...(Ts) << " arguments" << std::endl; }
template <typename L, typename ... Ts, std::size_t ... Is>
void f3_helper (L l, std::tuple<Ts...> const & t, std::index_sequence<Is...>)
{ l(std::get<Is>(t)...); }
template <typename L1, typename L2, typename ... As1, typename ... As2>
void f3 (L1 l1, L2 l2, std::tuple<As1...> const & t1,
std::tuple<As2...> const & t2)
{
f3_helper(l1, t1, std::index_sequence_for<As1...>{});
f3_helper(l2, t2, std::index_sequence_for<As2...>{});
}
int main()
{
auto l1 = [](auto && ... args)
{ f1(std::forward<decltype(args)>(args)...); };
auto l2 = [](auto && ... args)
{ f2(std::forward<decltype(args)>(args)...); };
f3(l1, l2, std::make_tuple(1, 2l, '3'), std::make_tuple('4', 5ull));
}
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 多态性和功能结合
- 带内存和隔离功能的SQLite
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++中获得"静态纯虚拟"功能?
- 两个文件使用彼此的功能-如何解决
- 我应该实现右值推送功能吗?我应该使用std::move吗
- QML按钮点击功能执行顺序
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 有没有可能有一个只有ADL才能找到的非好友功能
- 功能样式转换从 'int' 到 'ItemType' 的匹配转换
- 文件系统:复制功能的速度秘诀是什么
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 如何在Directwrite中获得给定字体的可用OpenType功能
- 对可变参数使用声明.如何选择正确的功能
- 询问在设计我的手臂模拟器功能表示格式1
- 功能原型的目的
- 这里在 Linux 中具有"CreatePipe"和"CreateProcessW"功能吗?