Can we just have one function with variadic templates?

I am taking the code from the solution to one of the old question from here

#include <utility>
#include <iostream>
class Test {
  public:
  Test() {
      std::cout << "ctor" << std::endl;
  }
  Test(const Test&) {
      std::cout << "copy ctor" << std::endl;
  }
  Test(Test&&) {
      std::cout << "move ctor" << std::endl;
  }
};

void func(Test const&)
{
    std::cout << "requires lvalue" << std::endl;
}

void func(Test&&)
{
    std::cout << "requires rvalue" << std::endl;
}

template<typename Arg>
void pass(Arg&& arg) {
    // use arg here
    func(std::forward<Arg>(arg));
    return; 
}

template<typename Arg, typename ...Args>
void pass(Arg&& arg, Args&&... args)
{
    // use arg here
    return pass(std::forward<Args>(args)...);
}

int main(int, char**)
{
    pass(std::move<Test>(Test()));
    return 0;
}

I am wondering if there exists a way to avoid having 2 overloads of the function called pass above something like void pass(Arg&& ...arg) and still achieve the same functionality as above?

It confuses me to understand when do I need to overloads like taken in above code.


In C++17, your might use fold expressions:

template <typename ... Ts>
void pass(Ts&&... args)
{
    [[maybe_unused]] auto f = [](auto&& arg){ /* use arg here */};
    (f(std::forward<Ts>(args)), ...);
    func((std::forward<Ts>(args), ...)); // call func only on last parameter
                                      // (assuming no evil overload of operator,)
}

Not exactly what you asked but... observe that (also before C++17) instead of a template ground-case recursion function that receive an arg and duplicate the single arg management

template <typename Arg>
void pass (Arg && arg) {
    func(std::forward<Arg>(arg));
}

you can simply write a non-template empty (no arg received, no arg managed) pass() function

void pass ()
{ }