之间有什么区别 带有转发参考参数的功能模板
template<typename T>
void Universal_func(T && a)
{
}
和缩写功能模板?
void auto_fun(auto && a)
{
}
我可以将Universal_func
替换为auto_fun
吗?是Universal_func
是auto_fun
还是等于?
我测试过以下程序。似乎两者都是一样的。
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
和auto_fun
推导并扩展到类似的功能。
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
有什么不同吗?标准说了什么?
答案 0 :(得分:10)
auto
还不是标准C ++的一部分,但是一些最新版本的GCC允许将其作为扩展,作为它们对Concepts TS的支持的一部分。
概念TS将此构造称为缩写的函数模板(虽然它曾经被称为泛型函数,我认为这个术语过于通用了) 。规则可能太大而无法转入此答案,但请查看this draft [dcl.fct]/16-19
中的所有血腥细节。
第16段提供了一个体面的概述:
缩写函数模板是参数类型列表包含的函数声明 一个或多个占位符(7.1.6.4)。缩写的函数模板等同于函数 template(14.6.6),其template-parameter-list包含一个发明的模板参数 每次出现在parameter-declaration-clause中的占位符,按照出现的顺序, 根据以下规则。 [注意:也发明了模板参数来推断出 声明类型包含占位符时变量的类型或函数的返回类型 (7.1.6.4.1)。 - 结束说明]
根据该草案中规定的规则,您的两个定义在功能上是等同的。
我们使用占位符参数:
void auto_fun(auto && a)
{
}
创建一个模板参数,将其替换为:
template <typename T>
void auto_fun (T && a)
{
}
如您所见,它与没有占位符的函数具有相同的签名:
template <typename T>
void Universal_func(T && a)
{
}