To write a variadic function that can accept both lvalue and rvalue arguments, you can use forwarding references (also known as universal references) in the parameter pack. Forwarding references are declared using the &&
syntax with a deduced type (auto or template type parameter).
Here's an example:
#include <iostream>
// Variadic function using forwarding references
template <typename... Types>
void PrintValues(Types&&... Args) {
(std::cout << ... << std::forward<Types>(Args))
<< '\n';
}
int main() {
int a = 10;
const std::string b = "hello";
// lvalues
PrintValues(a, b);
// rvalues
PrintValues(20, std::string("world"));
}
10hello
20world
In this example, PrintValues()
uses forwarding references Types&&... Args
to capture both lvalue and rvalue arguments. Inside the function, std::forward<Types>(Args)
is used to forward the arguments to std::cout
while preserving their value category.
When PrintValues()
is called with lvalue arguments a
and b
, the compiler deduces the template arguments as int&
and const std::string&
respectively. The arguments are forwarded as lvalue references.
When PrintValues()
is called with rvalue arguments 20
and std::string("world")
, the compiler deduces the template arguments as int&&
and std::string&&
respectively. The arguments are forwarded as rvalue references.
By using forwarding references, the variadic function can accept and forward both lvalue and rvalue arguments, avoiding unnecessary copying and enabling perfect forwarding.
It's important to note that if you don't need to modify the arguments and want to avoid potential dangling references, you can use const Types&...
instead of Types&&...
to capture lvalues and rvalues as const references.
template <typename... Types>
void PrintValuesConstRef(const Types&... Args) {
(std::cout << ... << Args) << '\n';
}
This version captures both lvalues and rvalues as const references, preventing modification and avoiding dangling references, but it does not enable perfect forwarding.
Answers to questions are automatically generated and may not have been reviewed.
An introduction to variadic functions, which allow us to pass a variable quantity of arguments