c++ - 多个可变参数模板函数

标签 c++ c++11 templates variadic-templates variadic-functions

<分区>

假设我有两个函数 f1()f2() 定义如下:

template<class ... Types> void f1(Types ... args1)
template<class ... Types> void f2(Types ... args2)

现在我想创建第三个函数 f3() 接受输入 f1()f2(),我该如何定义f3() 同时包含 args1...args2...

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

而不是全套功能。

我能建议的最好的方法是将模板函数包装在结构中

struct s1
 {
   template <typename ... Types>
   static void f1 (Types ... args1)
    { }
 };

struct s2
 {
   template <typename ... Types>
   static void f2 (Types ... args2)
    { }
 };

所以你可以传递给 f3() s1s2 对象

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)

what I mean is when I call f3, I offer f1 and f2. I also need to pass in the params for f1 and f2. How do I do that?

但是 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:之前从元组中提取参数有点复杂。

how do I do that without c++17?

以下是使用 std::index_sequence_forstd::index_sequence 解包元组的完整 C++14 示例

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

关于c++ - 多个可变参数模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54013345/

相关文章:

c++ - 在不同的线程上调用和执行函数

c++为什么这个错误 "basic_string::substr"并打破循环

c++ - 如何确定 STL 容器中的最后一个有效元素

c++ - 当 C++11 应用程序使用非 C++11 库时返回值损坏

android - 为什么 android studio 在应用文件模板后进行 gradle 同步?

C++ 模板 - 广义操作和实例之间成员的可见性

c++ - 非虚拟多重继承示例

c++ - 将执行从一个线程转移到另一个线程以实现任务并行性和 future 调用

c++ - 如何为具有自定义类型的 std::vector 创建显式模板实例化声明?

c++ - 类定义中构造函数的模板特化