What are the differences between function templates with forwarding reference parameters
template<typename T>
void Universal_func(T && a)
{
}
and abbreviated function templates?
void auto_fun(auto && a)
{
}
Can I replace Universal_func
with auto_fun
? Is Universal_func
a of auto_fun
or are they equal?
I have tested the below program. It seems that both are the same.
template<typename T>
void Universal_func(T && a)
{
}
void auto_fun(auto && a)
{
}
int main()
{
int i;
const int const_i = 0;
const int const_ref =const_i;
//forwarding reference template function example
Universal_func(1); //call void Universal_func<int>(int&&)
Universal_func(i);//call void Universal_func<int&>(int&):
Universal_func(const_i); //call void Universal_func<int const&>(int const&)
Universal_func(const_ref);//call void Universal_func<int const&>(int const&)
//auto calls
auto_fun(1); //call void auto_fun<int>(int&&)
auto_fun(i);//call void auto_fun<int&>(int&):
auto_fun(const_i); //call void auto_fun<int const&>(int const&)
auto_fun(const_ref);//call void auto_fun<int const&>(int const&)
return 0;
}
Universal_func
and auto_fun
deduced and expanded to similar functions.
void Universal_func<int>(int&&):
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
nop
popq %rbp
ret
void Universal_func<int&>(int&):
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
nop
popq %rbp
ret
void Universal_func<int const&>(int const&):
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
nop
popq %rbp
ret
void auto_fun<int>(int&&):
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
nop
popq %rbp
ret
void auto_fun<int&>(int&):
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
nop
popq %rbp
ret
void auto_fun<int const&>(int const&):
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
nop
popq %rbp
ret
Are there any differences? What does the standard say?
auto
in function parameters is not part of standard C++ yet, but some recent versions of GCC allow this as an extension as part of their support for the Concepts TS.The Concepts TS refers to this construct as an abbreviated function template (although it used to be known as a generic function, which I guess was too generic a term). The rules are perhaps too large to dump into this answer, but have a look in
[dcl.fct]/16-19
in this draft for all the gory details.Paragraph 16 provides a decent overview:
By the rules set forth in that draft, your two definitions are functionally equivalent.
We take the function with a placeholder parameter:
And invent a template parameter to replace it with:
As you can see, this has the same signature as your function without placeholders: