C++ 为什么不能使用auto重载功能?
我知道使用C++ 为什么不能使用auto重载功能?,c++,auto,overloading,c++14,C++,Auto,Overloading,C++14,我知道使用模板是一种值得赞赏的重载方式,但我想知道为什么自动不能用于函数参数类型推断,从而有助于函数重载 N3690在7.6.1.4/3中指出,可以使用auto使lambda表达式成为通用表达式,提供了以下示例 auto glambda = [](int i, auto a) { return i; };//OK: a generic lambda (注:N3485中未提及) 1) 为什么我不能为一个正常的函数做类似的事情 void swap(auto& param1, decltyp
模板
是一种值得赞赏的重载方式,但我想知道为什么自动
不能用于函数参数类型推断,从而有助于函数重载
N3690
在7.6.1.4/3中指出,可以使用auto使lambda表达式成为通用表达式,提供了以下示例
auto glambda = [](int i, auto a) { return i; };//OK: a generic lambda
(注:N3485中未提及)
1) 为什么我不能为一个正常的函数做类似的事情
void swap(auto& param1, decltype(param1)& param2)
{
decltype(param1) temp = param1;
param1 = param2;
param2 = temp;
}
这会产生错误错误:参数声明为自动
来自N3690 7.1.6.4/4
使用auto或decltype(auto)声明的变量类型是从其
初始化器。在块(6.3)中、命名空间范围(3.3.6)中和for init语句(6.5.3)中声明变量时,允许使用此用法
我认为param1
和param2
属于块范围,因此有资格自动扣除,这是错误的吗
2) 。如果允许这样的功能,会有什么陷阱
我使用的是GCC4.8.1
谢谢你n3690 7.1.6.4/2
占位符类型可以与函数声明符一起出现在decl说明符seq、类型说明符seq、, 在此类声明符有效的任何上下文中,转换函数id或尾部返回类型。
7.1.6.4/3如果自动类型说明符在参数的decl说明符序列中显示为decl说明符之一- 声明lambda表达式时,lambda是泛型lambda。
7.1.6.4/4使用auto或decltype(auto)声明的变量类型是从其初始值设定项推导出来的。这个用途很简单- 在块(6.3)、命名空间范围(3.3.6)和for init语句(6.5.3)中声明变量时降低。 auto或decltype(auto)应作为decl说明符seq和decl中的一个decl说明符出现- 说明符seq后面应跟随一个或多个初始声明符,每个初始声明符应具有非空的首字母- 喷雾器。
7.1.6.4/5 占位符类型也可用于在选择语句(6.4)或 在新类型id或新表达式(5.3.4)的类型id的类型说明符seq中的迭代语句(6.5) 用于范围声明,以及在声明带有大括号或相等初始值设定项的静态数据成员时 在类别定义(9.4.2)的成员规范内。 只有这样的用法是禁止的。禁止任何其他用法(特别是参数声明条款
中的用法)
7.1.6.4/6
在本节中未明确允许的上下文中使用Autoor或DeCype(Autoto)的程序是不正确的。< /P> < P36N3690是C++ 14的委员会草案,即对于尚未发布的C++标准,在大多数编译器中可能还未实现。因此,如果实现了泛型lambda,您应该参考编译器的文档,我想它们不是 然而,有了gcc,您很有可能在新标准正式发布之前实现C++14功能,尽管您可能需要使用命令行标志显式地启用C++14支持。查看文档,它应该是
-std=gnu++1y
据介绍,通用lambda尚未在GCC中实现
更新:
至于使用auto
参数的普通通用函数:这些参数不存在,下次也不会出现。原因是模板化函数对于类型来说只是稍微详细一些,而且功能更强大一些,因为您可以引用类型并直接将模板元函数应用于它们。在泛型lambda中,这只能通过使用decltype(a)
来实现,这有点繁琐,必须小心使用,因为它的行为与模板参数推断稍有不同。与自动参数相比,模板的另一个好处是更具类型安全性或表达能力:
void func(auto a, auto b); //a and b might be different types
template <class T>
void func(T a, T b); //a and b must be the same type
void func(自动a、自动b)//a和b可能是不同的类型
模板
无效函数(T a,T b)//a和b必须是同一类型
位于的顶部:
为什么我不能为一个正常的函数做类似的事情
void swap(auto& param1, decltype(param1)& param2)
{
decltype(param1) temp = param1;
param1 = param2;
param2 = temp;
}
只是因为语言不允许这样。在C++11中(重新)发明auto
之前,可以通过模板实现您想要的:
template <class T, class U>
void swap(T& param1, U& param2);
最后,首选的语法是使用auto
,而不是引入模板参数列表
的确,人们可以考虑将这种语法语法扩展到函数模板(如OP建议的那样),但据我所知,委员会还没有考虑过这种可能性。将来可能会这样,但必须有人正式提出。这可能是一个“很好的特性”,但我认为这只是语法上的糖分,并没有给语言带来太多
此外,我看不出如何将这种简洁的语法(没有模板参数列表)用于模板类,也许将模板函数的语法与模板类的语法分开是不值得的。已经有了一种编写所需内容的方法:-
template <class T>
void swap(T& param1, T& param2)
{
T temp = param1;
param1 = param2;
param2 = temp;
}
模板
无效掉期(T¶m1、T¶m2)
{
T温度=参数1;
param1=param2;
参数2=温度;
}
那么,为什么要创建一种新的语法,它不允许您做以前做不到的事情呢。建议对lambdas进行的更改是允许使用以前无法使用的通用lambdas,我想任何使用模板语法的语法在这里都会很难看 据我所知,lambdas的自动参数是C++14,而不是C++11。@RalphTandetzky哦,好的<代码>N3690力似乎提到了这一点,所以我感到困惑。是的,它是在2013年5月15日发布的,所以我猜它一定是c++14。但我还是想知道这是否可行?@Koushik在发布之前不要使用c++14标记。@永远谢谢你。我现在才明白原因。永远都是这样的,对兰姆达来说应该是这样的,对吧?但lambda的参数可以取au
template <class T>
void swap(T& param1, T& param2)
{
T temp = param1;
param1 = param2;
param2 = temp;
}