【问题标题】:How the C++0x standard defines C++ Auto multiple declarations?C++0x 标准如何定义 C++ Auto 多重声明?
【发布时间】:2010-10-04 08:25:53
【问题描述】:

嗯,我对即将到来的 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

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      draft standard 第 7.1.6.4 节暗示您不能像可能的翻译 2 那样混合类型。所以这两种可能的翻译都是无效的。

      【讨论】:

      • 可能的翻译 1 永远不会有效,因为根据模板参数推导规则为 Class* 推导 T* 永远无法得到 T=int,在这种情况下使用该规则
      【解决方案3】:

      这可能不是最新的,但我 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 的推断类型具有相同的“基本类型”(在此case) 使用不精确的术语。

      如果您想要精确的规则,标准草案是这样说的:

      如果声明符列表包含多个声明符,则每个声明变量的类型按照描述确定 更多。如果每次推导模板参数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?
      

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

      【讨论】:

        【解决方案4】:

        我认为有几点有助于促成当前的措辞。首先是一致性。如果您编写如下声明:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-16
          • 1970-01-01
          • 2011-08-06
          • 1970-01-01
          • 2010-10-08
          • 1970-01-01
          相关资源
          最近更新 更多