我一直在使用c++ 11标准中提供的新的auto关键字来处理复杂的模板类型,我相信它就是为这个目的设计的。但我也用它来做以下事情:

auto foo = std::make_shared<Foo>();

更令人怀疑的是:

auto foo = bla(); // where bla() return a shared_ptr<Foo>

我还没有看到很多关于这个话题的讨论。auto似乎被滥用了,因为类型通常是一种文档和完整性检查的形式。你在使用auto方面的界限在哪里,这个新功能的推荐用例是什么?

澄清一下:我并不是在寻求哲学观点;我要求标准委员会对这个关键字的预期使用,可能还会对如何在实践中实现预期使用发表评论。


当前回答

Auto关键字只能用于局部变量,不能用于参数或类/结构成员。所以,在任何你喜欢的地方使用它们都是安全可行的。我确实经常使用它们。类型在编译时推导,调试器在调试时显示类型,sizeof正确报告它,decltype将给出正确的类型——没有伤害。我从不认为auto是过度使用的!

其他回答

我使用auto的一个痛苦经历是在lambda表达式中使用它:

auto i = []() { return 0; };
cout<<"i = "<<i<<endl; // output: 1 !!!

实际上,这里i被解析为int(*)()的函数指针。这只是一个简单的cout,但是想象一下,当它与template一起使用时,会导致什么样的编译/运行时错误。

你应该避免使用这样的表达式,并设置一个合适的返回类型(或受控的decltype())

上述例子的正确用法是:

auto i = []() { return 0; }(); // and now i contains the result of calling the lambda  

Auto关键字只能用于局部变量,不能用于参数或类/结构成员。所以,在任何你喜欢的地方使用它们都是安全可行的。我确实经常使用它们。类型在编译时推导,调试器在调试时显示类型,sizeof正确报告它,decltype将给出正确的类型——没有伤害。我从不认为auto是过度使用的!

是的,它可能被过度使用而损害可读性。我建议在这样的情况下使用它:确切的类型很长,或者无法表达,或者对可读性不重要,并且变量的寿命很短。例如,迭代器类型通常很长,不重要,所以auto可以工作:

   for(auto i = container.begin(); i != container.end(); ++i);

这里的Auto不会影响可读性。

另一个例子是解析器规则类型,它可能很长很复杂。比较:

   auto spaces = space & space & space;

with

r_and_t<r_and_t<r_char_t<char>&, r_char_t<char>&>, r_char_t<char>&> spaces = 
   space & space & space;

另一方面,当类型是已知的并且是简单的,如果显式地声明它会更好:

int i = foo();

而不是

auto i = foo();

什么汽车?

它告诉编译器根据变量的初始值推断(确定)变量的数据类型。它使用类型演绎。

auto应该用在哪里?

当你对变量的类型不感兴趣时 想要使用它。 当你想要避免非常长和丑陋的typename。 当你不确定自己的类型时。 当你不想在你的代码中看到未初始化的变量。 Auto强制你初始化一个变量,因此你不能忘记做 那

当它不应该使用或缺点的自动

参考它的功能,auto可能会错误地推断类型,1 这种情况是

Std::vector<bool> vec(10,0); Auto x = vec[2]; Bool y = vec[2]; Std::cout << typeid(x).name() << "\n"; Std::cout << typeid(y).name() << "\n";

g++ 10.2上的输出令人惊讶:

St14_Bit_reference

b

如果你想让你的代码可读&,不应该使用它 对其他人来说是可以理解的。它隐藏了数据类型的可见性 来自读者。

TL;DR:见底部的经验法则。

公认的答案包含以下经验法则:

当第一眼不知道如何写类型,但表达式右边的类型很明显时,请使用auto。

但我想说这太严格了。有时我并不关心类型,因为语句已经提供了足够的信息,而无需我花时间去弄清楚类型。这是什么意思呢?考虑一下一些答案中出现的例子:

auto x = f();

是什么使这个例子滥用auto?是我不知道f()的返回类型吗?好吧,如果我知道的话可能会有帮助,但是-这不是我主要关心的。更大的问题是x和f()是没有意义的。如果我们有:

auto nugget = mine_gold();

相反,我通常不关心函数的返回类型是否明显。读这个语句,我知道我在做什么,我对返回值的语义有足够的了解,所以我不觉得我还需要知道它的类型。

所以我的回答是:只要编译器允许,就使用auto,除非:

You feel the variable name together with the initialization / assignment expression do not provide enough information about what the statement is doing. You feel the variable name together with the initialization / assignment expression provides "misleading" information about what the type should be - i.e., if you had to guess what comes instead of the auto you would be able to make a guess - and it would be wrong, and this false assumption has repercussions later in the code. You want to force a different type (e.g. a reference).

还有:

在用具体类型替换auto之前,最好给出一个有意义的名称(当然不包含类型名)。