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

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)

在推断类型有意义的地方使用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

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

我使用auto没有任何限制,没有遇到任何问题。有时我甚至把它用于简单的类型,如int。这使得c++对我来说是一种更高级别的语言,并且允许在c++中像在python中一样声明变量。在写完python代码之后,我有时甚至会写例如。

auto i = MyClass();

而不是

MyClass i;

这是我认为auto关键字滥用的一种情况。

Often I don't mind what is the exact type of the object, I'm more interested in its fonctionality, and as function names generally say something about the objects they return, auto does not hurt: in e.g. auto s = mycollection.size(), I can guess that s will be a kind of integer, and in the rare case where I care about the exact type, let's check the function prototype then (I mean, I prefer to have to check when I need the info, rather than a priori when code is written, just in case it would be usefull someday, as in int_type s = mycollection.size()).

关于这个例子,从公认的答案:

for ( auto x = max_size; x > 0; --x )

在我的代码中,在这种情况下我仍然使用auto,如果我想让x是unsigned,那么我使用一个实用函数,命名为say make_unsigned,这清楚地表达了我的担忧:

for ( auto x = make_unsigned(max_size); x > 0; --x )

免责声明:我只是描述我的使用,我没有能力给出建议!

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

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();