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

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

更令人怀疑的是:

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

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

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


当前回答

我使用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 )

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

其他回答

什么汽车?

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

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

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可以工作:

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

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

这只是我的观点。