Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么自动说明符的类型推断只关心for循环的init字段?_C++_C++11_Auto_Type Deduction - Fatal编程技术网

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) { }