C++ 为什么自动说明符的类型推断只关心for循环的init字段?
以下示例似乎非常简单明了:C++ 为什么自动说明符的类型推断只关心for循环的init字段?,c++,c++11,auto,type-deduction,C++,C++11,Auto,Type Deduction,以下示例似乎非常简单明了: void ftest(size_t& arg) { std::cout << arg << '\n'; } int main() { size_t max = 5; for (auto i = 0; i < max; ++i) ftest(i); } void ftest(尺寸和参数) { std::cout因为变量的类型是在声明时确定的(从其初始值设定项),它与如何使用它无关。如果
void ftest(size_t& arg)
{
std::cout << arg << '\n';
}
int main()
{
size_t max = 5;
for (auto i = 0; i < max; ++i)
ftest(i);
}
void ftest(尺寸和参数)
{
std::cout因为变量的类型是在声明时确定的(从其初始值设定项),它与如何使用它无关。如果需要进行类型转换,将予以考虑。该规则与使用显式指定类型声明的变量相同,只是帮助您推导出类型,并不特殊
试着考虑一下:
auto max = 5u;
for (auto i = 0; i < max; ++i)
// ~~~~~~~~
// i should be unsigned int, or max should be int ?
关键字auto
与for
语句的其余部分没有任何关系,它也不知道。如果您说它应该从max
进行推断,您是说延迟类型推断,这将不符合auto
类型推断规则
另外,这个呢
size_t max = 5;
short min = 1;
for (auto i = 0; i < max && i > min; ++i)
size\u t max=5;
短min=1;
用于(自动i=0;imin;++i)
如果它推断为short
或size\u t
?你不能让编译器读懂你的心思
此外,这种延迟推理规则(如果有的话)会使模板元编程复杂化。
< P>你实际上提供了一个非常简单的情况,其中条件是一个简单的<代码> i,其中“<代码> max < /代码>的类型是已知的。标准试图提供适用于所有情况的规则,现在让我们考虑一下:
bool f(int);
bool f(size_t);
for (auto i = 0; f(i); ++i) { }
如果i
的类型依赖于for
循环中的条件表达式,则编译器可能不会满意
此外,Herb Sutter在其博客上发布了一篇关于这个问题的小帖子,实际上:这会使auto i=0
的含义依赖于上下文,我可以想象这会引起各种各样的混乱。您是否尝试过(auto i=0lu;i
?也许您还应该检查是否不需要初始化变量甚至出现在if
语句的其他部分,因此它的编译不可能依赖于它们。坦率地说,如果你这样编码,你首先就滥用了auto
的功能。这是为了减轻你对像std::map::const_迭代器It=mymap.cbegin()这样的已知诽谤的负担
并免费交付,auto-it=mymap.cbegin();
。简而言之,回答您的问题“在这样的for循环中,自动有什么意义?”-如您所示,在for循环中使用auto
是没有意义的。键入size\t
需要再击两下键,并消除任何第一眼的歧义。@DragonRock:假设std::是相同的
。其他合理的选择是0u
和0ull
,但当然没有f这些是可移植的。您解释了为什么auto
在一般情况下不依赖于上下文,而是在for
循环语句(不包括其主体)的情况下,您不能有多个auto
,因此标准可能为此提供了例外情况。@Holt但是怎么做?类型应该是什么,声明中使用的类型,还是比较中使用的类型?@juanchopanza可以使用适用于三元运算符的相同规则来推断类型,三元运算符已经是标准的一部分。我不是说这个w我个人更喜欢标准的ranges函数,就像python必须使用基于它们的range;)@Holt“三元”是一个表达式,因此auto x=
的工作方式与auto i=0
的工作方式相同。在这里,我们没有涉及比较中使用的类型的初始化表达式。因此,新规则必须非常复杂,并且我认为它们只会增加混乱。标准范围的语法将是一件非常有用的事情。例如,somet喜欢(auto i:[0..max])
@juanchopanza我同意这会让人困惑,但我不认为如果只有关系运算符,这会很复杂(但这是一个太特殊的情况…)有一个自定义语法真的很好,但是如果标准能够提供标准函数来生成range
结构,可以在for
循环中使用,例如for(auto I:range(0,max))
;)我不确定这实际上会有多复杂-这可能归结为必须计算auto t=true?0:(true?max:min)的类型)
,在本例中是size\u t
。如果变量i
只涉及运算符,则可以很容易地推导出来。但正如我在回答中提到的,这是一种特殊情况,标准并不“关心”特殊情况。@Holt:好的,假设模板t max(t);for(auto i=0;i
)。现在,
i`的类型取决于max(i)
的类型,这显然取决于i
的类型!实际上,for循环的条件表达式必须是(可转换的)对于bool
,您不能恰当地描述auto
应该如何从随机布尔表达式的一部分推断类型。@MSalters看到了我的答案,这恰恰暴露了这个问题。我的观点很简单,只涉及关系运算符的“简单”表达式可以推导出来,但这是一个非常特殊的情况(该标准不会为此类案件制定规则)。
bool f(int);
bool f(size_t);
for (auto i = 0; f(i); ++i) { }