mmm,我对即将推出的C ++ 0x标准中的多个自动声明感到有些困惑。
auto a = 10, b = 3.f , * c = new Class();
某处我不允许阅读。 原因是(?)因为不清楚连续声明是否应该与第一个声明具有相同的类型(在示例中为int),或者不是。
可能的翻译1:
int a = 10;
int b = 3.f;
int * c = new Class ();
导致错误
可能的翻译2:
int a = 10;
float b = 3.f;
Class * c = new Class ();
它是如何产生标准的?
如果我可以说我的POV,翻译#2是最常见的,至少对我而言,我是一名普通的C ++用户。我的意思是,对我来说“声明的每个变量都是相同的声明类型”,女巫是自动的。 翻译#1对我来说真的不直观。
再见。再见 QbProg答案 0 :(得分:6)
这可能不是最新的,但是从2008年6月起我的C ++ 0x草案标准说你可以做到以下几点:
auto x = 5; // OK: x has type int
const auto *v = &x, u = 6; // OK: v has type const int*, u has type const int
因此,除非从6月开始发生变化,否则这将是(或将会)以有限的形式进行,并且具有非常直观的解释。
如果您确实希望将这样的多个自动声明串起来(使用上面的示例),那么它的工作原理是因为v
和u
的推断类型具有相同的“基本类型” (在这种情况下为int)使用不精确的术语。
如果你想要准确的规则,标准草案就是这样说的:
如果声明符列表包含多个声明符,则每个声明的变量的类型将按所述方式确定 以上。如果模板参数U的推导类型在每次推断中不相同,则程序格式不正确。
其中“推导出的模板参数U”由下式确定:
以下发明的函数模板的调用f(expr)中的参数u的推导类型:
`template <class U> void f(const U& u);`
为什么他们提出这个规则而不是说:
auto a = 10, b = 3.f , * c = new Class();
相当于:
auto a = 10;
auto b = 3.f;
auto * c = new Class();
我不知道。但我不写编译器。可能与您在找到auto
关键字替换后有关,您无法在同一语句中更改它。
以例如:
int x = 5;
CFoo * c = new CFoo();
auto a1 = x, b1 = c; // why should this be permitted if
int a2 = x, CFoo* b2 = c; // this is not?
无论如何,我不喜欢将多个声明放在同一个声明中。
答案 1 :(得分:4)
draft standard第7.1.6.4节暗示您不能像可能的翻译那样混合类型2.因此,两种可能的翻译都无效。
答案 2 :(得分:2)
我认为有助于当前措辞的几点。首先是一致性。如果你写一个声明,如:
int j;
int i = 0, *k = &j;
然后,这两种类型都在其类型的某处使用 int 。例如,如果'j'是'const int',那就是错误。 auto 的工作方式与此类声明的当前模型“一致”。
从编译器编写者的角度来看,有一个实际的优势。编译器中已存在机器来执行函数调用的类型推导(这是 auto 被描述为操作的方式)。上述规则与模板参数的推导必须导致相同类型的规则一致:
template <typename T> void foo (T, T*);
void bar ()
{
int i;
const int j = 0;
foo (i, &i); // OK deduction succeeds T == int
foo (i, &j); // ERROR deduction fails T == int or const int.
}
auto 的一个简单实现是重用现有的机制来推断 auto 的类型,并且由于与当前行为的一致性,结果不会太令人惊讶给人们。
最后,这可能是我认为最重要的一点。当前模型是保守的,与C ++中现有的语言结构非常相似。因此,它导致节目停止语言错误的可能性非常小。但是,将来可以轻松扩展当前模型,以包含您在问题中列出的其他示例。
更重要的是,扩展不会破坏使用 auto 当前措辞的代码。考虑一下他们是否这样做了。如果 auto 的扩展版本是第一个版本,并且这导致了关键字的一些奇怪和致命的缺陷,那么它将需要从标准中删除语言特征 - 这几乎从未发生过它最有可能打破代码。
答案 3 :(得分:0)
第一个类似于类型推断如何在?:运算符的返回类型中运行。