我一直在使用c++ 11标准中提供的新的auto关键字来处理复杂的模板类型,我相信它就是为这个目的设计的。但我也用它来做以下事情:
auto foo = std::make_shared<Foo>();
更令人怀疑的是:
auto foo = bla(); // where bla() return a shared_ptr<Foo>
我还没有看到很多关于这个话题的讨论。auto似乎被滥用了,因为类型通常是一种文档和完整性检查的形式。你在使用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可以工作:
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();
一件容易的事。当你不关心是什么类型时使用它。例如
for (const auto & i : some_container) {
...
这里我只关心I是容器里的东西。
它有点像typedefs。
typedef float Height;
typedef double Weight;
//....
Height h;
Weight w;
这里,我不关心h和w是浮点数还是双精度浮点数,只关心它们是任何适合表示高度和权重的类型。
或者考虑
for (auto i = some_container .begin (); ...
这里我只关心它是一个合适的迭代器,支持运算符++(),在这方面有点像鸭子类型。
此外,lambdas的类型不能拼写,因此auto f =[]…是好的风格。另一种方法是强制转换为std::function,但这会带来开销。
我真的无法想象对汽车的“滥用”。我能想到的最接近的是剥夺你自己到一些重要类型的显式转换——但你不会使用auto,你会构造一个所需类型的对象。
如果您可以在不引入副作用的情况下删除代码中的一些冗余,那么这样做一定是好的。
反例(借用别人的回答):
auto i = SomeClass();
for (auto x = make_unsigned (y); ...)
这里我们确实关心类型是什么,所以我们应该写Someclass i;And for(unsigned x = y;…
什么汽车?
它告诉编译器根据变量的初始值推断(确定)变量的数据类型。它使用类型演绎。
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
如果你想让你的代码可读&,不应该使用它
对其他人来说是可以理解的。它隐藏了数据类型的可见性
来自读者。