有什么优雅的方式吗?(类型参数包)

Is there any elegant way? (type parameter pack)

本文关键字:类型参数 方式吗 什么      更新时间:2023-10-16

我想制作一个接受类型的函数,并通过循环或递归再次调用自己。

我已经尝试过的是下面,但它仅称为基本函数(用AModule类称为基本功能,并且没有使用BModule.

调用该功能
class AModule {
};
class BModule {
};
auto main() -> int {
  init<AModule, BModule>()
  return 0;
}
template<typename Module>
void init() {
  // BASE FUNCTION
  // Do something
}
template<typename... Modules>
void init() {
  (init<Modules>(), ...)
}

在您的示例中,您正在使用模板折叠,这是一个新的C 17功能,可允许您避免递归。

但是,为了避免名称碰撞,我建议以不同的方式调用基本版本;说 do_something()

template<typename Module>
void do_something() {
  // BASE FUNCTION
  // Do something
}
template<typename... Modules>
void init() {
  (do_something<Modules>(), ...);
}

如果您真的想使用递归方式,则可以按照以下操作

template <int = 0>
void init ()
 {
  // stop recursion; do nothing
 }
template <typename Head, typename ... Tail>
void init () 
 {
   // do something with Head
   // recursively call init()
   init<Tail...>();
 }

诀窍是调用init<Tail...>();,直到Tail...不为空之前称为Head/Tail...递归版本。

Tail...为空时,init<Tail...>()init<>(),因此Head/Tail...版本不再匹配(没有Head),但与int = 0版本匹配;因此,init<>()成为init<0>(),而无需地面案件停止递归。

在您的代码中(一旦修复了语法错误),两个init()调用对于1个模板参数有效,因此调用模棱两可。通过进行多点呼叫需要至少2个参数,可以删除歧义。

// bogus type that just prints an error message including the type it is parameterized with
template<typename T>
struct printer;
template<typename Module>
void init() {
 printer<Module>{}; // this is an error just to show you that it's getting called with both types
}
// only call this if it's called with 2 or more types, otherwise just use the other init()
template<typename T1, typename T2, typename... Modules>
void init() {
    init<T1>();
    init<T2>();
  (init<Modules>(), ...);
}
class AModule {
};
class BModule {
};
auto main() -> int {
  init<AModule, BModule>();
  return 0;
}

live:https://godbolt.org/z/d-eh2g