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

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

更令人怀疑的是:

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

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

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


当前回答

在推断类型有意义的地方使用auto。如果你知道它是一个整数,或者你知道它是一个字符串,只需使用int / std::string等。我不担心“过度使用”一种语言特性,除非它达到荒谬的地步,或者混淆代码。

这只是我的观点。

其他回答

什么汽车?

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

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

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

我指出的一个危险是在引用方面。 如。

MyBigObject& ref_to_big_object= big_object;
auto another_ref = ref_to_big_object; // ?

问题是,在这种情况下,another_ref实际上不是一个引用,它是MyBigObject而不是MyBigObject&。你最终复制了一个大对象而没有意识到它。

如果你直接从一个方法中得到一个引用,你可能不会考虑它实际上是什么。

auto another_ref = function_returning_ref_to_big_object();

你需要"auto&"或者"const auto&"

MyBigObject& ref_to_big_object= big_object;
auto& another_ref = ref_to_big_object;
const auto& yet_another_ref = function_returning_ref_to_big_object();

我使用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关键字。例如,使用:

my_multi_type::nth_index<2>::type::key_type::composite_key_type::
    key_extractor_tuple::tail_type::head_type::result_type

要在boost::multi_index中获取复合键类型,即使您知道它是int。你不能只写int,因为它将来可能会被改变。在这种情况下我会写auto。

因此,如果auto关键字在特定情况下提高了可读性,那么就使用它。当读者很清楚auto所代表的类型时,可以使用auto。

下面是一些例子:

auto foo = std::make_shared<Foo>();   // obvious
auto foo = bla();                     // unclear. don't know which type `foo` has

const size_t max_size = 100;
for ( auto x = max_size; x > 0; --x ) // unclear. could lead to the errors
                                      // since max_size is unsigned

std::vector<some_class> v;
for ( auto it = v.begin(); it != v.end(); ++it )
                                      // ok, since I know that `it` has an iterator type
                                      // (don't really care which one in this context)