简体   繁体   中英

variadic template with recursive control

I need a template function that checks if the first value is among those that follow.


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

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.

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. 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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