简体   繁体   English

具有递归控制的可变参数模板

[英]variadic template with recursive control

I need a template function that checks if the first value is among those that follow.我需要一个模板 function 来检查第一个值是否在后面的值中。


I thought I would try something like this but it doesn't work我以为我会尝试这样的事情,但它不起作用

template<class T, class U>
bool is_in_set(const T &t, const U &u) {
  return t == u;
}

template<class T, class ...Args>
bool is_in_set(const T &t, Args...args) {
  return false || is_in_set(t, args...);
}

It compiles but I got the following warning warning C4717: 'is_in_set': recursive on all control paths, function will cause runtime stack overflow它可以编译,但我收到以下警告warning C4717: 'is_in_set': recursive on all control paths, function will cause runtime stack overflow

Can anyone help me to fix it and explain me why it doesn't work?谁能帮我修复它并解释为什么它不起作用?

From C++17, you can write this function with a fold-expression , which is simpler than writing a recursive function with a base case.从 C++17 开始,您可以使用fold-expression编写此 function,这比使用基本情况编写递归 function 更简单。

template<class T, class ...Args>
bool is_in_set(T const & t, Args const & ...args) 
{
  return (... || (t == args));
}

And now you can call it like this.现在你可以这样称呼它。

is_in_set(1, 2, 3, 4);  // false
is_in_set(1, 2, 1, 4);  // true

Here's a demo这是一个演示


Considering your code, you're getting the warning because you have an infinite recursion on this line:考虑到您的代码,您会收到警告,因为您在此行有无限递归:

return false || is_in_set(t, args...);  // infinite recursion here

Note that you're calling the function template recursively with exactly the same arguments.请注意,您使用完全相同的 arguments 递归调用 function 模板。 This means you'll recurse infinitely, and never reach the base case.这意味着您将无限递归,并且永远不会达到基本情况。

You can fix this by naming the second argument and taking the remaining arguments as a parameter pack.您可以通过命名第二个参数并将剩余的 arguments 作为参数包来解决此问题。

template<class T, class U>
bool is_in_set(T const & t, U const &u) 
{
    return t == u;
}
  
template<class T, class U, class ...Args>
bool is_in_set(T const & t, U const & u, Args const &...args) 
{ 
  return is_in_set(t, u) || is_in_set(t, args...);
}

Here's a demo这是一个演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM