Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.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++;不允许在一个自动语句中使用多个类型? 2011 C++标准引入了新的关键字 Audio/Cuff>,它可以用来定义变量而不是类型,即 auto p=make_pair(1,2.5); // pair<int,double> auto i=std::begin(c), end=std::end(c); // decltype(std::begin(c))_C++_C++11_For Loop_Auto - Fatal编程技术网

为什么C++;不允许在一个自动语句中使用多个类型? 2011 C++标准引入了新的关键字 Audio/Cuff>,它可以用来定义变量而不是类型,即 auto p=make_pair(1,2.5); // pair<int,double> auto i=std::begin(c), end=std::end(c); // decltype(std::begin(c))

为什么C++;不允许在一个自动语句中使用多个类型? 2011 C++标准引入了新的关键字 Audio/Cuff>,它可以用来定义变量而不是类型,即 auto p=make_pair(1,2.5); // pair<int,double> auto i=std::begin(c), end=std::end(c); // decltype(std::begin(c)),c++,c++11,for-loop,auto,C++,C++11,For Loop,Auto,当x为不同类型时我的问题:为什么标准不允许最后一行?可以通过解释auto来允许它,而不是表示某些要被删除的类型,而是表示任何声明的auto变量的类型应从其赋值中推导出来。C++11标准有什么理由不遵循这种方法吗 实际上,这有一个用例,即在for循环的初始化语句中: for(auto i=std::begin(c), end=std::end(c), x=*i; i!=end; ++i, x+=*i) { ... } 当变量i、end和x的范围限于for循环时。除非这些变量有一个公共类型,否

x
为不同类型时我的问题:为什么标准不允许最后一行?可以通过解释
auto
来允许它,而不是表示某些要被删除的类型,而是表示任何声明的
auto
变量的类型应从其赋值中推导出来。C++11标准有什么理由不遵循这种方法吗

实际上,这有一个用例,即在
for
循环的初始化语句中:

for(auto i=std::begin(c), end=std::end(c), x=*i;  i!=end;  ++i, x+=*i)
{ ... }
当变量
i
end
x
的范围限于
for
循环时。除非这些变量有一个公共类型,否则C++不能实现这一点。strong>这是否正确?(排除了将所有类型放入
结构中的丑陋技巧)


在一些可变模板应用中也可能有用例。

< P>如果引用C++ 2014工作草案,则标准允许这样的代码。
auto x = 5, *y = &x; // OK: auto is int

我想补充一点,在您的示例中,无法推断自动,因为迭代器类型和迭代器的值类型是两种不同的类型。

根据此功能的最终版本,可能的多声明器
自动
实现如下:(来自第6节)

我们相信有可能实现一致的形式和效果 一贯的行为。我们通过插入(为了 exposition)中间类型定义,并应用 此类型在“仿佛”扩展中保持一致:

我们不仅通过这样一种方式实现了形式和行为的一致性 通过协调表述,我们还可以解决更复杂的情况。 例如,当前导声明符包括ptr运算符时:

我们的公式附加语义,如同声明:

如此可能的实现所示,更改类型将无效,因此将导致错误。
此功能是以这种方式实现的,因为否则它将不同于其他类型的多变量声明。

我记得看到一场关于是否允许更改类型的讨论,但我不记得在哪里。IIRC,他们决定这将更难实现,但另一个原因可能是因为他们无法就何时选择不同类型(新行为)或何时隐式转换为第一个声明变量的推导类型(旧行为)达成共识而放弃了它.

我认为这只是一个与非
自动声明的一致性问题

这:

相当于:

int n = 42, *p = &n;
其中,类型
int
int*
来自初始值设定项。在这两种情况下,尽管
int
int*
是不同的类型,但由于它们的语法关系密切,允许它们位于同一个声明中。通过“声明遵循使用”规则,C和C++声明几乎遵循,您定义的是“代码> N<代码/代码>和<代码> *P<代码>类型为<代码> int 可以在同一声明中允许不相关的类型:

auto n = 42, x = 1.5;
但上述声明必须相当于两个单独的声明:

int n = 42; double x = 1.5;
我认为添加
auto
的想法是对语言进行最小的更改,允许从初始值设定项推断类型,但不改变可能的声明类型

即使没有
auto
,也可以在
循环头的
中定义
int
int*

for (int n = 42, *p = &n; expr1; expr2) { /* ... / }
但是不能同时声明
int
double
。添加
auto
并没有改变这一点

for
循环的上下文之外,通常最好使用单独的声明。在大多数情况下,将大量不同的声明推入
for
循环可能是一个坏主意。对于需要大量声明的(可能很少)情况,您可以将它们放在循环之上,如下所示:

auto i=std::begin(c), end=std::end(c),
for( x=*i;  i!=end;  ++i, x+=*i) {
    // ...
}

如果要限制范围,请在整个事件周围添加另一组
{
}
。(在这种情况下,您可能希望
end
成为
const

C++17最终带来了结构化绑定声明,解决了您的问题:

auto [ i, s, f ] = std::tuple(42, "Hello World", 5.0);
这将i声明为整数42,s声明为以零结尾的字符串“Hello World”,s声明为常量char*
,f声明为双精度数字5.0

我不知道没有中间
std::tuple
的解决方案。如果使用完全一致的C++20编译器,还可以使用别名模板缩写
std::tuple
,如本例所示:

template<typename ... ARGS> using T = std::tuple<ARGS ...>;
auto [ i, s, f ] = T(42, "Hello World", 5.0);
使用T=std::tuple的
模板;
自动[i,s,f]=T(42,“你好世界”,5.0);

这可以在C++17和C++20模式下使用
g++-10
很好地编译,尽管它实际上应该只在C++20模式下编译。C++17不允许对别名模板进行模板参数推断,即使在最简单的情况下,模板参数列表以1:1的比例转发到别名模板。

几乎所有形式为“标准为什么说废话”的问题都有以下答案之一:1)与C的向后兼容性,2)他们没有时间做其他事情,3)[在这里插入未经证实的意见]@JohnDibling我不同意。通常有很好的理由(除了向后兼容性,这里似乎不适用)。我想知道这里是否有充分的理由。约翰是对的。几乎所有这样的问题最终都会得到这样的答案。他不是说有充分的理由这么做
int n = 42; double x = 1.5;
for (int n = 42, *p = &n; expr1; expr2) { /* ... / }
auto i=std::begin(c), end=std::end(c),
for( x=*i;  i!=end;  ++i, x+=*i) {
    // ...
}
auto [ i, s, f ] = std::tuple(42, "Hello World", 5.0);
template<typename ... ARGS> using T = std::tuple<ARGS ...>;
auto [ i, s, f ] = T(42, "Hello World", 5.0);