为什么不放弃" auto"关键词?

时间:2015-03-25 09:47:50

标签: c++ c++11 initialization auto

现在我在c ++ 11中引入了auto关键字,我认为我们应该可以删除指定auto并简单地将变量初始化为v = 20。由于C ++能够自己推断变量的类型,为什么不将auto关键字全部放在一起并在第一次初始化时推导出变量的类型?

例如,而不是这个,

int main() {
    auto v = 20;
}

为什么不说,

int main() {
    v = 20;
}

(假设与全局变量没有冲突)

4 个答案:

答案 0 :(得分:16)

您的提案将仅在向后兼容性的基础上被拒绝。但是,为了论证,标准委员会喜欢你的想法。

  1. 您没有考虑初始化变量的众多方法
  2. widget w;                   // (a)
    
    widget w();                 // (b)
    widget w{};                 // (c)
    
    widget w(x);                // (d)
    widget w{x};                // (e)
    
    widget w = x;               // (f)
    widget w = {x};             // (g)
    
    auto w = x;                 // (h)
    auto w = widget{x};         // (i)
    

    w()应该是什么意思?它是默认构造名为w的变量,还是在名为w的变量上调用调用运算符?它是否创建了一个函数声明(它的类型是什么?如何推断出这样一个函数的类型?)

    认识到widget w()是一个函数声明的事实完全忽略了这一点。关键是语言不像x = some_value那样干脆。

    请注意,省略基于范围的for循环的初始值设定项的提议不适用于该语言的其余部分。它在这里工作,因为变量的范围仅限于循环,因为你被迫初始化一个变量(总是使用auto&&)。

    for (i : {1, 2, 3}) { }
    
    1. auto不是魔术,它使用模板参数演绎
    2. C ++不是动态类型的语言。推导auto类型的规则假装变量被传递给假想的模板化函数。如果扣除会像通常那样失败,则无法创建变量。目前存在一个缺陷,其中以下内容将创建std::initializer_list而不是使用标量初始化变量:

      auto a{4}; // initializer list of one element, not an int
      auto{4}; // not allowed
      

      你会如何处理这种情况?

答案 1 :(得分:4)

TL; DR:我不赞成。

实际上,在python的第一个初始化策略中声明是非常危险的。它实际上意味着在确保没有变量输入错误之前不应该向客户发送任何python代码,也不是几乎从不发生的恢复代码。当然,C ++代码也必须彻底测试,但至少这些错误会被编译器捕获。

我甚至建议通过一个工具运行python代码,该工具检查类的所有变量是否在__init__()中分配,但添加成员变量的类除外。

错字很容易制作,一些测试可以监督:

def my_func():
  my_check = do_some_checks()
  if my_check:
    my_chek = do_more_checks()
  return my_check

VS

bool myFunc()
{
  auto myCheck = doSomeChecks();
  if (myCheck)
  {
    myChek = doMoreChecks();
  }
  return myCheck;
}

底线:如果您让它成为您的朋友,编译器可以成为您的朋友。

答案 2 :(得分:3)

你不明白这里的问题。当有auto时,编译器知道有一个声明和初始化的变量,但没有auto,它就像一个表达式。像

auto v=20;

此处v声明并初始化。但没有自动

v=20;

它将类似于对变量的赋值,该变量先前已声明并且附加了一个内存空间。

答案 3 :(得分:2)

允许这些事情的问题超出了好处。例如;

//  warning:  this is code to illustrate a problem with the proposal
//       it is not valid C++ (thankfully)

int main()
{
     alpha = 20;  

     //   do stuff

     Alpha= 30;    //   typo here.  We have introduced a new variable


     // do funky stuff that produces incorrect results if alpha has a value of 20    
}

这里的问题是,所提出的“特性”将通过创建第二个变量(默认情况下)来静默地允许代码进行编译。编程由这些事件导致的错误(两个或多个具有类似名称的变量,在视觉上类似于程序员只打算成为一个变量)通常很难追踪。避免此类错误是几种编程语言(包括C和C ++)不允许隐式声明变量的重要原因之一。这些错误很容易被编译器或解释器检测到,即使凡人都无法发现它们。

还有其他编程语言允许这种事情。对这些语言的一个相当普遍的批评是容易引入我描述的许多小错误,所以开发人员必须(如果他们测试代码很好)花费数小时追踪这些简单的事情,因为没有编译器/解释器的帮助。 / p>