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 ()
{ }