提问人:koegl 提问时间:11/16/2023 更新时间:11/16/2023 访问量:80
为什么我需要在递归中使用参数包 [duplicate]
Why do I need constexpr in recursion with parameter packs [duplicate]
问:
我有一个简单的递归函数来打印参数包中的每个参数
#include <iostream>
template<typename T, typename... Args>
void printArgs(T first, Args... rest) {
std::cout << first << " ";
if constexpr (sizeof...(rest) > 0) { // doesn't compile without constexpr
printArgs(rest...);
} else {
return;
}
}
int main() {
printArgs(1, 2, "hello");
return 0;
}
问1:为什么我需要在程序中编译?
Q2: 条件不应该是吗?因为如果大小是,我再打电话,那不会是空的吗?(可以是空的吗?constexpr
if
sizeof...(rest) > 1
1
printArgs
rest
我看到了类似的问题,比如优化的“constexpr if”与“if”——为什么需要“constexpr”?,但我不明白这些答案与我的情况有什么关系。
答:
此外,您不必使用显式递归,从 C++17 开始,您可以使用折叠表达式。
以下代码将输出1, 2, hello
#include <iostream>
template<typename First, typename... Args>
void printArgs(First&& first, Args&&... rest)
{
std::cout << std::forward<First>(first);
//https://en.cppreference.com/w/cpp/language/fold
// the part before ,... will be repeated/expanded
// each time with one argument
((std::cout << ", " << std::forward<Args>(rest)),...);
}
int main()
{
printArgs(1, 2, "hello");
return 0;
}
我将从第二个问题开始,因为这个问题的答案也解释了问题 1。
Q2:条件不应该是吗?因为如果大小是 1,我再次调用,那么不会是空的吗?(它是空的可以吗?
sizeof...(rest) > 1
printArgs
rest
你的错误是计算.但是如果你调用,那么 是从 和 是空的,并且是 .可以使用 1 () 加零或更多 () 参数来调用函数。T
sizeof...(rest)
printArgs(onlyOne)
T
onlyOne
Args
sizeof...(rest)
0
T first
Args... rest
Q1:为什么在if中需要constexpr才能编译程序?
如果删除 ,则会出现以下错误:constexpr
<source>: In instantiation of 'void printArgs(T, Args ...) [with T = const char*; Args = {}]':
<source>:8:18: recursively required from 'void printArgs(T, Args ...) [with T = int; Args = {const char*}]'
<source>:8:18: required from 'void printArgs(T, Args ...) [with T = int; Args = {int, const char*}]'
<source>:15:14: required from here
<source>:8:18: error: no matching function for call to 'printArgs()'
8 | printArgs(rest...);
| ~~~~~~~~~^~~~~~~~~
<source>:4:6: note: candidate: 'template<class T, class ... Args> void printArgs(T, Args ...)'
4 | void printArgs(T first, Args... rest) {
| ^~~~~~~~~
<source>:4:6: note: template argument deduction/substitution failed:
<source>:8:18: note: candidate expects at least 1 argument, 0 provided
8 | printArgs(rest...);
| ~~~~~~~~~^~~~~~~~~
因为在最后一次递归中,只有 1 个参数被传递给并且没有元素。在这种情况下,编译失败,因为(见上文)您的函数只能用 1 或更多调用。 导致 false 分支被丢弃,并且您调用的部分永远不会实例化。printArgs
rest
printArgs(rest...)
if constexpr
printArgs()
评论
if
printArgs()
printArgs(1)
Args... rest
else
if