Wal*_*ter 13 c++ for-loop auto c++11
2011 C++标准引入了new关键字auto,可用于定义变量而不是类型,即
auto p=make_pair(1,2.5); // pair<int,double>
auto i=std::begin(c), end=std::end(c); // decltype(std::begin(c))
Run Code Online (Sandbox Code Playgroud)
在第二行中,i并且end具有相同的类型,被称为的auto.该标准不允许
auto i=std::begin(container), e=std::end(container), x=*i;
Run Code Online (Sandbox Code Playgroud)
什么时候x会有不同的类型.我的问题:为什么标准不允许这最后一行?可以通过将其解释auto为不代表某些待定的类型,而是指示所声明的任何变量的类型auto应从其指定值推导出来.C++ 11标准有没有很好的理由不遵循这种方法?
实际上有一个用例,即在for循环的初始化语句中:
for(auto i=std::begin(c), end=std::end(c), x=*i; i!=end; ++i, x+=*i)
{ ... }
Run Code Online (Sandbox Code Playgroud)
当变量的范围i,end以及x被限制在for环路.AFAIK,除非这些变量具有通用类型,否则无法在C++中实现.它是否正确?(将所有类型放入struct排除的丑陋技巧)
在一些可变参数模板应用程序中也可能存在用例.
我认为这只是与非auto声明的一致性问题.
这个:
auto n = 42, *p = &n;
Run Code Online (Sandbox Code Playgroud)
相当于:
int n = 42, *p = &n;
Run Code Online (Sandbox Code Playgroud)
其中的类型int和int*派生自初始化器.在这两种情况下,即使int和int*有不同的类型,他们允许在相同的声明,因为他们的亲密关系句法的.(由"声明如下方式使用"规则,C和C++声明几乎跟随,你定义都n和*p为类型的int.)
可以在同一声明中允许不相关的类型:
auto n = 42, x = 1.5;
Run Code Online (Sandbox Code Playgroud)
但上述内容必须相当于两个单独的声明:
int n = 42; double x = 1.5;
Run Code Online (Sandbox Code Playgroud)
我认为添加时的想法auto是对语言进行最小的更改,允许从初始化程序推断类型,但不能更改可能的声明类型.
即使没有auto,您也可以在循环标题中定义一个int和一个:int*for
for (int n = 42, *p = &n; expr1; expr2) { /* ... / }
Run Code Online (Sandbox Code Playgroud)
但你不能一起声明一个int和一个double.添加auto简单并没有改变这一点.
在for循环的上下文之外,无论如何使用单独的声明通常要好得多.for在大多数情况下,将许多不同的声明推入循环可能是一个坏主意.对于需要大量声明的(可能是罕见的)情况,你可以将它们放在循环之上,如下所示:
auto i=std::begin(c), end=std::end(c),
for( x=*i; i!=end; ++i, x+=*i) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
{ }如果要限制范围,请添加另一组整个事物.(在这种情况下,你可能想end成为const反正.)
根据该特征的公认提案N1737的最终修订,可能的多声明器auto实现如下:(来自第6节)
我们相信可以实现一致的形式和一致的行为.我们通过插入(为了展示的目的)中间__Deduced_type定义,并在as-if扩展中一致地应用此类型来实现:
// Listing 12
typedef int __Deduced_type; // exposition only
__Deduced_type a = 1;
// decltype(a) is int
__Deduced_type b = 3.14; // decltype(b) is int
__Deduced_type * c = new float; // error; decltype(c) would be int *
Run Code Online (Sandbox Code Playgroud)
通过这种协调的表述,我们不仅可以实现形式和行为的一致性,还可以解决更复杂的情况.例如,当主要声明符包含ptr-operator时:
// Listing 13
auto * a = new int(1), b = 3.14, * c = new float;
Run Code Online (Sandbox Code Playgroud)
我们的配方附加了语义 - 如果声明:
// Listing 14
typedef int __Deduced_type; // exposition only
__Deduced_type * a = new int(1); // decltype(a) is int *
__Deduced_type b = 3.14; // decltype(b) is int
__Deduced_type * c = new float; // error; decltype(c) would be int *
Run Code Online (Sandbox Code Playgroud)
如此可能的实现所示,更改类型将无效,因此会导致错误.
此功能以这种方式实现,因为否则它将与其他类型的多变量声明不同.
我记得看到有关是否允许更改类型的讨论,但我不记得在哪里.IIRC,他们认为实施起来会更难,但另一个原因可能是它被删除了,因为他们无法就何时选择不同类型(新行为)或何时隐式转换为推导类型达成共识第一个声明的变量(旧行为).
| 归档时间: |
|
| 查看次数: |
4397 次 |
| 最近记录: |