2

嗯,我对即将到来的 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++ 用户。我的意思是,对我来说,“声明的每个变量都具有相同的声明类型”,witch 是自动的。翻译#1对我来说真的很不直观。

再见 QbProg

4

4 回答 4

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 月开始发生变化,否则(或将)以有限的形式允许使用非常直观的解释。

限制是,如果您确实想像这样(使用上面的示例)对多个自动声明进行字符串化,它会起作用,因为推断的类型vu具有相同的“基本类型”(在这种情况下为 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?

无论如何,无论如何,我都不喜欢在同一个语句上放置多个声明。

于 2009-01-29T21:34:42.030 回答
4

标准草案第7.1.6.4 节暗示您不能像可能的翻译 2 那样混合类型。因此,任何可能的翻译都无效。

于 2009-01-29T21:18:58.410 回答
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的扩展版本是第一个版本,并且这导致关键字出现一些奇怪和致命的缺陷,那么它将需要从标准中删除语言功能 - 这几乎不会发生,因为它很可能会破坏代码。

于 2009-01-30T12:31:16.040 回答
0

第一个将与类型推断在 ?: 运算符的返回类型中的工作方式一致。

于 2009-01-29T21:03:49.907 回答