有什么优雅的方法吗? (类型参数包)
Is there any elegant way? (type parameter pack)
我想制作一个接受类型并通过循环或递归再次调用自身的函数。
下面是我已经尝试过的,但它只调用了基本函数(Called base function with AModule
class and didn't call the function with 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>(), ...)
}
在您的代码中(修复语法错误后),两个 init()
调用都对 1 个模板参数有效,因此该调用不明确。通过使 multi-init 调用至少需要 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;
}
在您示例的代码中,您使用了模板折叠,这是一种新的 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>()
并且地面什么都不做的情况停止递归。
我想制作一个接受类型并通过循环或递归再次调用自身的函数。
下面是我已经尝试过的,但它只调用了基本函数(Called base function with AModule
class and didn't call the function with 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>(), ...)
}
在您的代码中(修复语法错误后),两个 init()
调用都对 1 个模板参数有效,因此该调用不明确。通过使 multi-init 调用至少需要 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;
}
在您示例的代码中,您使用了模板折叠,这是一种新的 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>()
并且地面什么都不做的情况停止递归。