问题
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?
回答1:
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:
An abbreviated function template is a function declaration whose parameter-type-list includes one or more placeholders (7.1.6.4). An abbreviated function template is equivalent to a function template (14.6.6) whose template-parameter-list includes one invented template-parameter for each occurrence of a placeholder in the parameter-declaration-clause, in order of appearance, according to the rules below. [ Note: Template parameters are also invented to deduce the type of a variable or the return type of a function when the declared type contains placeholders (7.1.6.4.1). — end note ]
By the rules set forth in that draft, your two definitions are functionally equivalent.
We take the function with a placeholder parameter:
void auto_fun(auto && a)
{
}
And invent a template parameter to replace it with:
template <typename T>
void auto_fun (T && a)
{
}
As you can see, this has the same signature as your function without placeholders:
template <typename T>
void Universal_func(T && a)
{
}
来源:https://stackoverflow.com/questions/34918814/abbreviated-function-template-vs-function-template-with-forwarding-reference-pa